Pass effect to API for sending.

This commit is contained in:
John Preston 2024-05-10 15:00:30 +04:00
parent d1106e5ae6
commit e120ae6ae6
5 changed files with 194 additions and 11 deletions

View file

@ -68,6 +68,9 @@ void Polls::create(
if (action.options.shortcutId) {
sendFlags |= MTPmessages_SendMedia::Flag::f_quick_reply_shortcut;
}
if (action.options.effectId) {
sendFlags |= MTPmessages_SendMedia::Flag::f_effect;
}
const auto sendAs = action.options.sendAs;
if (sendAs) {
sendFlags |= MTPmessages_SendMedia::Flag::f_send_as;

View file

@ -133,6 +133,9 @@ void SendExistingMedia(
flags |= MessageFlag::ShortcutMessage;
sendFlags |= MTPmessages_SendMedia::Flag::f_quick_reply_shortcut;
}
if (action.options.effectId) {
sendFlags |= MTPmessages_SendMedia::Flag::f_effect;
}
session->data().registerMessageRandomId(randomId, newId);
@ -144,6 +147,7 @@ void SendExistingMedia(
.date = HistoryItem::NewMessageDate(action.options),
.shortcutId = action.options.shortcutId,
.postAuthor = messagePostAuthor,
.effectId = action.options.effectId,
}, media, caption);
const auto performRequest = [=](const auto &repeatRequest) -> void {
@ -307,6 +311,9 @@ bool SendDice(MessageToSend &message) {
flags |= MessageFlag::ShortcutMessage;
sendFlags |= MTPmessages_SendMedia::Flag::f_quick_reply_shortcut;
}
if (action.options.effectId) {
sendFlags |= MTPmessages_SendMedia::Flag::f_effect;
}
session->data().registerMessageRandomId(randomId, newId);
@ -318,6 +325,7 @@ bool SendDice(MessageToSend &message) {
.date = HistoryItem::NewMessageDate(action.options),
.shortcutId = action.options.shortcutId,
.postAuthor = messagePostAuthor,
.effectId = action.options.effectId,
}, TextWithEntities(), MTP_messageMediaDice(
MTP_int(0),
MTP_string(emoji)));
@ -512,6 +520,7 @@ void SendConfirmedFile(
.shortcutId = file->to.options.shortcutId,
.postAuthor = messagePostAuthor,
.groupedId = groupId,
.effectId = file->to.options.effectId,
}, caption, media);
}

View file

@ -3383,6 +3383,7 @@ void ApiWrap::forwardMessages(
.date = HistoryItem::NewMessageDate(action.options),
.shortcutId = action.options.shortcutId,
.postAuthor = messagePostAuthor,
.effectId = action.options.effectId,
}, item);
_session->data().registerMessageRandomId(randomId, newId);
if (!localIds) {
@ -3483,6 +3484,7 @@ void ApiWrap::sendSharedContact(
.date = HistoryItem::NewMessageDate(action.options),
.shortcutId = action.options.shortcutId,
.postAuthor = messagePostAuthor,
.effectId = action.options.effectId,
}, TextWithEntities(), MTP_messageMediaContact(
MTP_string(phone),
MTP_string(firstName),
@ -3816,6 +3818,10 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
sendFlags |= MTPmessages_SendMessage::Flag::f_quick_reply_shortcut;
mediaFlags |= MTPmessages_SendMedia::Flag::f_quick_reply_shortcut;
}
if (action.options.effectId) {
sendFlags |= MTPmessages_SendMessage::Flag::f_effect;
mediaFlags |= MTPmessages_SendMedia::Flag::f_effect;
}
lastMessage = history->addNewLocalMessage({
.id = newId.msg,
.flags = flags,
@ -3824,6 +3830,7 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
.date = HistoryItem::NewMessageDate(action.options),
.shortcutId = action.options.shortcutId,
.postAuthor = messagePostAuthor,
.effectId = action.options.effectId,
}, sending, media);
const auto done = [=](
const MTPUpdates &result,
@ -4162,7 +4169,8 @@ void ApiWrap::sendMediaWithRandomId(
| (!sentEntities.v.isEmpty() ? Flag::f_entities : Flag(0))
| (options.scheduled ? Flag::f_schedule_date : Flag(0))
| (options.sendAs ? Flag::f_send_as : Flag(0))
| (options.shortcutId ? Flag::f_quick_reply_shortcut : Flag(0));
| (options.shortcutId ? Flag::f_quick_reply_shortcut : Flag(0))
| (options.effectId ? Flag::f_effect : Flag(0));
auto &histories = history->owner().histories();
const auto peer = history->peer;
@ -4271,7 +4279,8 @@ void ApiWrap::sendAlbumIfReady(not_null<SendingAlbum*> album) {
| (sendAs ? Flag::f_send_as : Flag(0))
| (album->options.shortcutId
? Flag::f_quick_reply_shortcut
: Flag(0));
: Flag(0))
| (album->options.effectId ? Flag::f_effect : Flag(0));
auto &histories = history->owner().histories();
const auto peer = history->peer;
histories.sendPreparedMessage(

View file

@ -128,9 +128,7 @@ namespace Media::Stories {
if (action.replyTo) {
sendFlags |= MTPmessages_SendMedia::Flag::f_reply_to;
}
const auto silentPost = ShouldSendSilent(
threadPeer,
action.options);
const auto silentPost = ShouldSendSilent(threadPeer, options);
if (silentPost) {
sendFlags |= MTPmessages_SendMedia::Flag::f_silent;
}
@ -140,6 +138,9 @@ namespace Media::Stories {
if (options.shortcutId) {
sendFlags |= MTPmessages_SendMedia::Flag::f_quick_reply_shortcut;
}
if (options.effectId) {
sendFlags |= MTPmessages_SendMedia::Flag::f_effect;
}
const auto done = [=] {
if (!--state->requests) {
if (show->valid()) {
@ -161,12 +162,10 @@ namespace Media::Stories {
MTP_long(randomId),
MTPReplyMarkup(),
MTPVector<MTPMessageEntity>(),
MTP_int(action.options.scheduled),
MTP_int(options.scheduled),
MTP_inputPeerEmpty(),
Data::ShortcutIdToMTP(
session,
action.options.shortcutId),
MTP_long(action.options.effectId)
Data::ShortcutIdToMTP(session, options.shortcutId),
MTP_long(options.effectId)
), [=](
const MTPUpdates &result,
const MTP::Response &response) {

View file

@ -12,9 +12,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "boxes/abstract_box.h"
#include "chat_helpers/compose/compose_show.h"
#include "core/shortcuts.h"
#include "history/view/media/history_view_sticker.h"
#include "history/view/reactions/history_view_reactions_selector.h"
#include "history/view/history_view_schedule_box.h"
#include "lang/lang_keys.h"
#include "ui/chat/chat_style.h"
#include "ui/chat/chat_theme.h"
#include "ui/widgets/buttons.h"
#include "ui/widgets/popup_menu.h"
#include "data/data_peer.h"
#include "data/data_forum.h"
@ -25,6 +29,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/history.h"
#include "history/history_unread_things.h"
#include "apiwrap.h"
#include "window/themes/window_theme.h"
#include "window/section_widget.h"
#include "styles/style_chat.h"
#include "styles/style_chat_helpers.h"
#include "styles/style_menu_icons.h"
@ -33,6 +40,33 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace SendMenu {
namespace {
class EffectPreview final : public Ui::RpWidget {
public:
EffectPreview(
not_null<QWidget*> parent,
std::shared_ptr<ChatHelpers::Show> show,
Details details,
QPoint position,
const Data::Reaction &effect,
Fn<void(Action, Details)> action);
private:
void paintEvent(QPaintEvent *e) override;
void mousePressEvent(QMouseEvent *e) override;
void setupGeometry(QPoint position);
void setupBackground();
void setupSend(Details details);
const std::shared_ptr<ChatHelpers::Show> _show;
const std::shared_ptr<Ui::ChatTheme> _theme;
const std::unique_ptr<Ui::ChatStyle> _chatStyle;
const std::unique_ptr<Ui::FlatButton> _send;
const Fn<void(Action, Details)> _actionWithEffect;
QRect _inner;
QImage _bg;
};
[[nodiscard]] Data::PossibleItemReactionsRef LookupPossibleEffects(
not_null<Main::Session*> session) {
auto result = Data::PossibleItemReactionsRef();
@ -51,6 +85,124 @@ namespace {
return result;
}
void ShowEffectPreview(
not_null<QWidget*> parent,
std::shared_ptr<ChatHelpers::Show> show,
Details details,
QPoint position,
const Data::Reaction &effect,
Fn<void(Action, Details)> action) {
const auto widget = Ui::CreateChild<EffectPreview>(
parent,
show,
details,
position,
effect,
action);
widget->raise();
widget->show();
}
[[nodiscard]] Fn<void(Action, Details)> ComposeActionWithEffect(
Fn<void(Action, Details)> sendAction,
EffectId id) {
if (!id) {
return sendAction;
}
return [=](Action action, Details details) {
if (const auto options = std::get_if<Api::SendOptions>(&action)) {
options->effectId = id;
}
sendAction(action, details);
};
}
EffectPreview::EffectPreview(
not_null<QWidget*> parent,
std::shared_ptr<ChatHelpers::Show> show,
Details details,
QPoint position,
const Data::Reaction &effect,
Fn<void(Action, Details)> action)
: RpWidget(parent)
, _show(show)
, _theme(Window::Theme::DefaultChatThemeOn(lifetime()))
, _chatStyle(
std::make_unique<Ui::ChatStyle>(
_show->session().colorIndicesValue()))
, _send(
std::make_unique<Ui::FlatButton>(
this,
u"Send with Effect"_q,AssertIsDebug()
st::previewMarkRead))
, _actionWithEffect(ComposeActionWithEffect(action, effect.id.custom())) {
setupGeometry(position);
setupBackground();
setupSend(details);
}
void EffectPreview::paintEvent(QPaintEvent *e) {
auto p = QPainter(this);
p.drawImage(0, 0, _bg);
}
void EffectPreview::mousePressEvent(QMouseEvent *e) {
delete this;
}
void EffectPreview::setupGeometry(QPoint position) {
const auto parent = parentWidget();
const auto innerSize = HistoryView::Sticker::MessageEffectSize();
const auto shadow = st::previewMenu.shadow;
const auto extend = shadow.extend;
_inner = QRect(QPoint(extend.left(), extend.top()), innerSize);
const auto size = _inner.marginsAdded(extend).size();
const auto left = std::max(
std::min(
position.x() - size.width() / 2,
parent->width() - size.width()),
0);
const auto topMin = std::min((parent->height() - size.height()) / 2, 0);
const auto top = std::max(
std::min(
position.y() - size.height() / 2,
parent->height() - size.height()),
topMin);
setGeometry(left, top, size.width(), size.height() + _send->height());
_send->setGeometry(0, size.height(), size.width(), _send->height());
}
void EffectPreview::setupBackground() {
const auto ratio = style::DevicePixelRatio();
_bg = QImage(
_inner.size() * ratio,
QImage::Format_ARGB32_Premultiplied);
const auto paint = [=] {
auto p = QPainter(&_bg);
Window::SectionWidget::PaintBackground(
p,
_theme.get(),
QSize(width(), height() * 5),
QRect(QPoint(), size()));
};
paint();
_theme->repaintBackgroundRequests() | rpl::start_with_next([=] {
paint();
update();
}, lifetime());
}
void EffectPreview::setupSend(Details details) {
_send->setClickedCallback([=] {
_actionWithEffect(Api::SendOptions(), details);
});
const auto type = details.type;
SetupMenuAndShortcuts(_send.get(), _show, [=] {
return Details{ .type = type };
}, _actionWithEffect);
}
} // namespace
Fn<void(Action, Details)> DefaultCallback(
@ -131,7 +283,18 @@ FillMenuResult FillSendMenu(
(*selector)->chosen(
) | rpl::start_with_next([=](ChosenReaction chosen) {
const auto &reactions = showForEffect->session().data().reactions();
const auto &effects = reactions.list(Data::Reactions::Type::Effects);
const auto i = ranges::find(effects, chosen.id, &Data::Reaction::id);
if (i != end(effects)) {
ShowEffectPreview(
menu,
showForEffect,
details,
menu->mapFromGlobal(chosen.globalGeometry.center()),
*i,
action);
}
}, menu->lifetime());
return FillMenuResult::Prepared;