mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-16 06:07:06 +02:00
Check effects availability in all SendMenu-s.
This commit is contained in:
parent
396ba9a984
commit
d1106e5ae6
50 changed files with 394 additions and 417 deletions
|
@ -910,12 +910,12 @@ CreatePollBox::CreatePollBox(
|
|||
PollData::Flags chosen,
|
||||
PollData::Flags disabled,
|
||||
Api::SendType sendType,
|
||||
SendMenu::Type sendMenuType)
|
||||
SendMenu::Details sendMenuDetails)
|
||||
: _controller(controller)
|
||||
, _chosen(chosen)
|
||||
, _disabled(disabled)
|
||||
, _sendType(sendType)
|
||||
, _sendMenuType(sendMenuType) {
|
||||
, _sendMenuDetails([result = sendMenuDetails] { return result; }) {
|
||||
}
|
||||
|
||||
rpl::producer<CreatePollBox::Result> CreatePollBox::submitRequests() const {
|
||||
|
@ -1288,20 +1288,9 @@ object_ptr<Ui::RpWidget> CreatePollBox::setupContent() {
|
|||
_submitRequests.fire({ collectResult(), sendOptions });
|
||||
}
|
||||
};
|
||||
const auto sendSilent = [=] {
|
||||
send({ .silent = true });
|
||||
};
|
||||
const auto sendScheduled = [=] {
|
||||
_controller->show(
|
||||
HistoryView::PrepareScheduleBox(
|
||||
this,
|
||||
_controller->uiShow(),
|
||||
SendMenu::Type::Scheduled,
|
||||
send));
|
||||
};
|
||||
const auto sendWhenOnline = [=] {
|
||||
send(Api::DefaultSendWhenOnlineOptions());
|
||||
};
|
||||
const auto sendAction = SendMenu::DefaultCallback(
|
||||
_controller->uiShow(),
|
||||
crl::guard(this, send));
|
||||
|
||||
options->scrollToWidget(
|
||||
) | rpl::start_with_next([=](not_null<QWidget*> widget) {
|
||||
|
@ -1314,25 +1303,23 @@ object_ptr<Ui::RpWidget> CreatePollBox::setupContent() {
|
|||
}, lifetime());
|
||||
|
||||
const auto isNormal = (_sendType == Api::SendType::Normal);
|
||||
|
||||
const auto schedule = [=] {
|
||||
sendAction(SendMenu::ActionType::Schedule, _sendMenuDetails());
|
||||
};
|
||||
const auto submit = addButton(
|
||||
isNormal
|
||||
(isNormal
|
||||
? tr::lng_polls_create_button()
|
||||
: tr::lng_schedule_button(),
|
||||
[=] { isNormal ? send({}) : sendScheduled(); });
|
||||
const auto sendMenuType = [=] {
|
||||
: tr::lng_schedule_button()),
|
||||
[=] { isNormal ? send({}) : schedule(); });
|
||||
const auto sendMenuDetails = [=] {
|
||||
collectError();
|
||||
return (*error)
|
||||
? SendMenu::Type::Disabled
|
||||
: _sendMenuType;
|
||||
return (*error) ? SendMenu::Details() : _sendMenuDetails();
|
||||
};
|
||||
SendMenu::SetupMenuAndShortcuts(
|
||||
submit.data(),
|
||||
_controller->uiShow(),
|
||||
sendMenuType,
|
||||
sendSilent,
|
||||
sendScheduled,
|
||||
sendWhenOnline);
|
||||
sendMenuDetails,
|
||||
sendAction);
|
||||
addButton(tr::lng_cancel(), [=] { closeBox(); });
|
||||
|
||||
return result;
|
||||
|
|
|
@ -27,7 +27,7 @@ class SessionController;
|
|||
} // namespace Window
|
||||
|
||||
namespace SendMenu {
|
||||
enum class Type;
|
||||
struct Details;
|
||||
} // namespace SendMenu
|
||||
|
||||
class CreatePollBox : public Ui::BoxContent {
|
||||
|
@ -43,7 +43,7 @@ public:
|
|||
PollData::Flags chosen,
|
||||
PollData::Flags disabled,
|
||||
Api::SendType sendType,
|
||||
SendMenu::Type sendMenuType);
|
||||
SendMenu::Details sendMenuDetails);
|
||||
|
||||
[[nodiscard]] rpl::producer<Result> submitRequests() const;
|
||||
void submitFailed(const QString &error);
|
||||
|
@ -75,7 +75,7 @@ private:
|
|||
const PollData::Flags _chosen = PollData::Flags();
|
||||
const PollData::Flags _disabled = PollData::Flags();
|
||||
const Api::SendType _sendType = Api::SendType();
|
||||
const SendMenu::Type _sendMenuType;
|
||||
const Fn<SendMenu::Details()> _sendMenuDetails;
|
||||
base::unique_qptr<ChatHelpers::TabbedPanel> _emojiPanel;
|
||||
Fn<void()> _setInnerFocus;
|
||||
Fn<rpl::producer<bool>()> _dataIsValidValue;
|
||||
|
|
|
@ -328,7 +328,7 @@ SendFilesBox::SendFilesBox(
|
|||
const TextWithTags &caption,
|
||||
not_null<PeerData*> toPeer,
|
||||
Api::SendType sendType,
|
||||
SendMenu::Type sendMenuType)
|
||||
SendMenu::Details sendMenuDetails)
|
||||
: SendFilesBox(nullptr, {
|
||||
.show = controller->uiShow(),
|
||||
.list = std::move(list),
|
||||
|
@ -337,7 +337,7 @@ SendFilesBox::SendFilesBox(
|
|||
.limits = DefaultLimitsForPeer(toPeer),
|
||||
.check = DefaultCheckForPeer(controller, toPeer),
|
||||
.sendType = sendType,
|
||||
.sendMenuType = sendMenuType,
|
||||
.sendMenuDetails = [=] { return sendMenuDetails; },
|
||||
}) {
|
||||
}
|
||||
|
||||
|
@ -350,7 +350,9 @@ SendFilesBox::SendFilesBox(QWidget*, SendFilesBoxDescriptor &&descriptor)
|
|||
, _titleHeight(st::boxTitleHeight)
|
||||
, _list(std::move(descriptor.list))
|
||||
, _limits(descriptor.limits)
|
||||
, _sendMenuType(descriptor.sendMenuType)
|
||||
, _sendMenuDetails(descriptor.sendMenuDetails
|
||||
? descriptor.sendMenuDetails
|
||||
: [] { return SendMenu::Details(); })
|
||||
, _captionToPeer(descriptor.captionToPeer)
|
||||
, _check(std::move(descriptor.check))
|
||||
, _confirmedCallback(std::move(descriptor.confirmed))
|
||||
|
@ -530,10 +532,8 @@ void SendFilesBox::refreshButtons() {
|
|||
SendMenu::SetupMenuAndShortcuts(
|
||||
_send,
|
||||
_show,
|
||||
[=] { return _sendMenuType; },
|
||||
[=] { sendSilent(); },
|
||||
[=] { sendScheduled(); },
|
||||
[=] { sendWhenOnline(); });
|
||||
_sendMenuDetails,
|
||||
SendMenu::DefaultCallback(_show, sendCallback()));
|
||||
}
|
||||
addButton(tr::lng_cancel(), [=] { closeBox(); });
|
||||
_addFile = addLeftButton(
|
||||
|
@ -546,7 +546,7 @@ void SendFilesBox::refreshButtons() {
|
|||
}
|
||||
|
||||
bool SendFilesBox::hasSendMenu() const {
|
||||
return (_sendMenuType != SendMenu::Type::Disabled);
|
||||
return (_sendMenuDetails().type != SendMenu::Type::Disabled);
|
||||
}
|
||||
|
||||
bool SendFilesBox::hasSpoilerMenu() const {
|
||||
|
@ -607,11 +607,11 @@ void SendFilesBox::addMenuButton() {
|
|||
if (hasSendMenu()) {
|
||||
SendMenu::FillSendMenu(
|
||||
_menu.get(),
|
||||
_sendMenuType,
|
||||
[=] { sendSilent(); },
|
||||
[=] { sendScheduled(); },
|
||||
[=] { sendWhenOnline(); },
|
||||
&_st.tabbed.icons);
|
||||
_show,
|
||||
_sendMenuDetails(),
|
||||
SendMenu::DefaultCallback(_show, sendCallback()),
|
||||
&_st.tabbed.icons,
|
||||
QCursor::pos());
|
||||
}
|
||||
_menu->popup(QCursor::pos());
|
||||
return true;
|
||||
|
@ -1426,7 +1426,9 @@ void SendFilesBox::send(
|
|||
if ((_sendType == Api::SendType::Scheduled
|
||||
|| _sendType == Api::SendType::ScheduledToUser)
|
||||
&& !options.scheduled) {
|
||||
return sendScheduled();
|
||||
return SendMenu::DefaultCallback(_show, sendCallback())(
|
||||
SendMenu::ActionType::Schedule,
|
||||
_sendMenuDetails());
|
||||
}
|
||||
if (_preparing) {
|
||||
_whenReadySend = [=] {
|
||||
|
@ -1464,25 +1466,10 @@ void SendFilesBox::send(
|
|||
closeBox();
|
||||
}
|
||||
|
||||
void SendFilesBox::sendSilent() {
|
||||
send({ .silent = true });
|
||||
}
|
||||
|
||||
void SendFilesBox::sendScheduled() {
|
||||
const auto type = (_sendType == Api::SendType::ScheduledToUser)
|
||||
? SendMenu::Type::ScheduledToUser
|
||||
: _sendMenuType;
|
||||
const auto callback = [=](Api::SendOptions options) { send(options); };
|
||||
auto box = HistoryView::PrepareScheduleBox(this, _show, type, callback);
|
||||
const auto weak = Ui::MakeWeak(box.data());
|
||||
_show->showBox(std::move(box));
|
||||
if (const auto strong = weak.data()) {
|
||||
strong->setCloseByOutsideClick(false);
|
||||
}
|
||||
}
|
||||
|
||||
void SendFilesBox::sendWhenOnline() {
|
||||
send(Api::DefaultSendWhenOnlineOptions());
|
||||
Fn<void(Api::SendOptions)> SendFilesBox::sendCallback() {
|
||||
return crl::guard(this, [=](Api::SendOptions options) {
|
||||
send(options, false);
|
||||
});
|
||||
}
|
||||
|
||||
SendFilesBox::~SendFilesBox() = default;
|
||||
|
|
|
@ -47,7 +47,7 @@ class SessionController;
|
|||
} // namespace Window
|
||||
|
||||
namespace SendMenu {
|
||||
enum class Type;
|
||||
struct Details;
|
||||
} // namespace SendMenu
|
||||
|
||||
namespace HistoryView::Controls {
|
||||
|
@ -96,7 +96,7 @@ struct SendFilesBoxDescriptor {
|
|||
SendFilesLimits limits = {};
|
||||
SendFilesCheck check;
|
||||
Api::SendType sendType = {};
|
||||
SendMenu::Type sendMenuType = {};
|
||||
Fn<SendMenu::Details()> sendMenuDetails = nullptr;
|
||||
const style::ComposeControls *stOverride = nullptr;
|
||||
SendFilesConfirmed confirmed;
|
||||
Fn<void()> cancelled;
|
||||
|
@ -115,7 +115,7 @@ public:
|
|||
const TextWithTags &caption,
|
||||
not_null<PeerData*> toPeer,
|
||||
Api::SendType sendType,
|
||||
SendMenu::Type sendMenuType);
|
||||
SendMenu::Details sendMenuDetails);
|
||||
SendFilesBox(QWidget*, SendFilesBoxDescriptor &&descriptor);
|
||||
|
||||
void setConfirmedCallback(SendFilesConfirmed callback) {
|
||||
|
@ -202,9 +202,7 @@ private:
|
|||
void generatePreviewFrom(int fromBlock);
|
||||
|
||||
void send(Api::SendOptions options, bool ctrlShiftEnter = false);
|
||||
void sendSilent();
|
||||
void sendScheduled();
|
||||
void sendWhenOnline();
|
||||
[[nodiscard]] Fn<void(Api::SendOptions)> sendCallback();
|
||||
void captionResized();
|
||||
void saveSendWaySettings();
|
||||
|
||||
|
@ -238,7 +236,7 @@ private:
|
|||
std::optional<int> _removingIndex;
|
||||
|
||||
SendFilesLimits _limits = {};
|
||||
SendMenu::Type _sendMenuType = {};
|
||||
Fn<SendMenu::Details()> _sendMenuDetails = nullptr;
|
||||
PeerData *_captionToPeer = nullptr;
|
||||
SendFilesCheck _check;
|
||||
SendFilesConfirmed _confirmedCallback;
|
||||
|
|
|
@ -473,15 +473,18 @@ void ShareBox::keyPressEvent(QKeyEvent *e) {
|
|||
}
|
||||
}
|
||||
|
||||
SendMenu::Type ShareBox::sendMenuType() const {
|
||||
SendMenu::Details ShareBox::sendMenuDetails() const {
|
||||
const auto selected = _inner->selected();
|
||||
return ranges::all_of(
|
||||
const auto type = ranges::all_of(
|
||||
selected | ranges::views::transform(&Data::Thread::peer),
|
||||
HistoryView::CanScheduleUntilOnline)
|
||||
? SendMenu::Type::ScheduledToUser
|
||||
: (selected.size() == 1 && selected.front()->peer()->isSelf())
|
||||
? SendMenu::Type::Reminder
|
||||
: SendMenu::Type::Scheduled;
|
||||
|
||||
// We can't support effect here because we don't have ChatHelpers::Show.
|
||||
return { .type = type, .effectAllowed = false };
|
||||
}
|
||||
|
||||
void ShareBox::showMenu(not_null<Ui::RpWidget*> parent) {
|
||||
|
@ -518,15 +521,25 @@ void ShareBox::showMenu(not_null<Ui::RpWidget*> parent) {
|
|||
_menu->addSeparator();
|
||||
}
|
||||
|
||||
const auto result = SendMenu::FillSendMenu(
|
||||
using namespace SendMenu;
|
||||
const auto sendAction = crl::guard(this, [=](Action action, Details) {
|
||||
const auto options = std::get_if<Api::SendOptions>(&action);
|
||||
if (options || v::get<ActionType>(action) == ActionType::Send) {
|
||||
submit(options ? *options : Api::SendOptions());
|
||||
} else {
|
||||
submitScheduled();
|
||||
}
|
||||
});
|
||||
_menu->setForcedVerticalOrigin(Ui::PopupMenu::VerticalOrigin::Bottom);
|
||||
const auto result = FillSendMenu(
|
||||
_menu.get(),
|
||||
sendMenuType(),
|
||||
[=] { submitSilent(); },
|
||||
[=] { submitScheduled(); },
|
||||
[=] { submitWhenOnline(); });
|
||||
const auto success = (result == SendMenu::FillMenuResult::Success);
|
||||
if (_descriptor.forwardOptions.show || success) {
|
||||
_menu->setForcedVerticalOrigin(Ui::PopupMenu::VerticalOrigin::Bottom);
|
||||
nullptr, // showForEffect.
|
||||
sendMenuDetails(),
|
||||
sendAction);
|
||||
if (result == SendMenu::FillMenuResult::Prepared) {
|
||||
_menu->popupPrepared();
|
||||
} else if (_descriptor.forwardOptions.show
|
||||
&& result != SendMenu::FillMenuResult::Failed) {
|
||||
_menu->popup(QCursor::pos());
|
||||
}
|
||||
}
|
||||
|
@ -607,26 +620,18 @@ void ShareBox::submit(Api::SendOptions options) {
|
|||
}
|
||||
}
|
||||
|
||||
void ShareBox::submitSilent() {
|
||||
submit({ .silent = true });
|
||||
}
|
||||
|
||||
void ShareBox::submitScheduled() {
|
||||
const auto callback = [=](Api::SendOptions options) { submit(options); };
|
||||
uiShow()->showBox(
|
||||
HistoryView::PrepareScheduleBox(
|
||||
this,
|
||||
nullptr, // ChatHelpers::Show for effect attachment.
|
||||
sendMenuType(),
|
||||
sendMenuDetails(),
|
||||
callback,
|
||||
HistoryView::DefaultScheduleTime(),
|
||||
_descriptor.scheduleBoxStyle));
|
||||
}
|
||||
|
||||
void ShareBox::submitWhenOnline() {
|
||||
submit(Api::DefaultSendWhenOnlineOptions());
|
||||
}
|
||||
|
||||
void ShareBox::copyLink() const {
|
||||
if (const auto onstack = _descriptor.copyCallback) {
|
||||
onstack();
|
||||
|
|
|
@ -24,7 +24,7 @@ struct PeerList;
|
|||
} // namespace style
|
||||
|
||||
namespace SendMenu {
|
||||
enum class Type;
|
||||
struct Details;
|
||||
} // namespace SendMenu
|
||||
|
||||
namespace Window {
|
||||
|
@ -130,13 +130,11 @@ private:
|
|||
void scrollAnimationCallback();
|
||||
|
||||
void submit(Api::SendOptions options);
|
||||
void submitSilent();
|
||||
void submitScheduled();
|
||||
void submitWhenOnline();
|
||||
void copyLink() const;
|
||||
bool searchByUsername(bool useCache = false);
|
||||
|
||||
SendMenu::Type sendMenuType() const;
|
||||
[[nodiscard]] SendMenu::Details sendMenuDetails() const;
|
||||
|
||||
void scrollTo(Ui::ScrollToRequest request);
|
||||
void needSearchByUsername();
|
||||
|
|
|
@ -1014,7 +1014,7 @@ void StickerSetBox::Inner::contextMenuEvent(QContextMenuEvent *e) {
|
|||
_menu = base::make_unique_q<Ui::PopupMenu>(
|
||||
this,
|
||||
st::popupMenuWithIcons);
|
||||
const auto type = _show->sendMenuType();
|
||||
const auto details = _show->sendMenuDetails();
|
||||
if (setType() == Data::StickersType::Emoji) {
|
||||
if (const auto t = PrepareTextFromEmoji(_pack[index]); !t.empty()) {
|
||||
_menu->addAction(tr::lng_mediaview_copy(tr::now), [=] {
|
||||
|
@ -1023,17 +1023,16 @@ void StickerSetBox::Inner::contextMenuEvent(QContextMenuEvent *e) {
|
|||
}
|
||||
}, &st::menuIconCopy);
|
||||
}
|
||||
} else if (type != SendMenu::Type::Disabled) {
|
||||
} else if (details.type != SendMenu::Type::Disabled) {
|
||||
const auto document = _pack[index];
|
||||
const auto sendSelected = [=](Api::SendOptions options) {
|
||||
const auto send = crl::guard(this, [=](Api::SendOptions options) {
|
||||
chosen(index, document, options);
|
||||
};
|
||||
});
|
||||
SendMenu::FillSendMenu(
|
||||
_menu.get(),
|
||||
type,
|
||||
SendMenu::DefaultSilentCallback(sendSelected),
|
||||
SendMenu::DefaultScheduleCallback(_show, type, sendSelected),
|
||||
SendMenu::DefaultWhenOnlineCallback(sendSelected));
|
||||
_show,
|
||||
details,
|
||||
SendMenu::DefaultCallback(_show, send));
|
||||
|
||||
const auto show = _show;
|
||||
const auto toggleFavedSticker = [=] {
|
||||
|
|
|
@ -23,10 +23,6 @@ namespace Data {
|
|||
class StickersSet;
|
||||
} // namespace Data
|
||||
|
||||
namespace SendMenu {
|
||||
enum class Type;
|
||||
} // namespace SendMenu
|
||||
|
||||
namespace ChatHelpers {
|
||||
struct FileChosen;
|
||||
class Show;
|
||||
|
|
|
@ -22,7 +22,7 @@ class SessionController;
|
|||
} // namespace Window
|
||||
|
||||
namespace SendMenu {
|
||||
enum class Type;
|
||||
struct Details;
|
||||
} // namespace SendMenu
|
||||
|
||||
namespace ChatHelpers {
|
||||
|
@ -57,7 +57,7 @@ public:
|
|||
[[nodiscard]] virtual rpl::producer<> pauseChanged() const = 0;
|
||||
|
||||
[[nodiscard]] virtual rpl::producer<bool> adjustShadowLeft() const;
|
||||
[[nodiscard]] virtual SendMenu::Type sendMenuType() const = 0;
|
||||
[[nodiscard]] virtual SendMenu::Details sendMenuDetails() const = 0;
|
||||
|
||||
virtual bool showMediaPreview(
|
||||
Data::FileOrigin origin,
|
||||
|
|
|
@ -1104,7 +1104,7 @@ void EmojiListWidget::fillRecentFrom(const std::vector<DocumentId> &list) {
|
|||
}
|
||||
|
||||
base::unique_qptr<Ui::PopupMenu> EmojiListWidget::fillContextMenu(
|
||||
SendMenu::Type type) {
|
||||
const SendMenu::Details &details) {
|
||||
if (v::is_null(_selected)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -144,7 +144,7 @@ public:
|
|||
RectPart origin);
|
||||
|
||||
base::unique_qptr<Ui::PopupMenu> fillContextMenu(
|
||||
SendMenu::Type type) override;
|
||||
const SendMenu::Details &details) override;
|
||||
|
||||
protected:
|
||||
void visibleTopBottomUpdated(
|
||||
|
|
|
@ -87,7 +87,7 @@ public:
|
|||
Api::SendOptions options = {}) const;
|
||||
|
||||
void setRecentInlineBotsInRows(int32 bots);
|
||||
void setSendMenuType(Fn<SendMenu::Type()> &&callback);
|
||||
void setSendMenuDetails(Fn<SendMenu::Details()> &&callback);
|
||||
void rowsUpdated();
|
||||
|
||||
rpl::producer<FieldAutocomplete::MentionChosen> mentionChosen() const;
|
||||
|
@ -155,7 +155,7 @@ private:
|
|||
const std::unique_ptr<Ui::PathShiftGradient> _pathGradient;
|
||||
StickerPremiumMark _premiumMark;
|
||||
|
||||
Fn<SendMenu::Type()> _sendMenuType;
|
||||
Fn<SendMenu::Details()> _sendMenuDetails;
|
||||
|
||||
rpl::event_stream<FieldAutocomplete::MentionChosen> _mentionChosen;
|
||||
rpl::event_stream<FieldAutocomplete::HashtagChosen> _hashtagChosen;
|
||||
|
@ -835,8 +835,9 @@ bool FieldAutocomplete::chooseSelected(ChooseMethod method) const {
|
|||
return _inner->chooseSelected(method);
|
||||
}
|
||||
|
||||
void FieldAutocomplete::setSendMenuType(Fn<SendMenu::Type()> &&callback) {
|
||||
_inner->setSendMenuType(std::move(callback));
|
||||
void FieldAutocomplete::setSendMenuDetails(
|
||||
Fn<SendMenu::Details()> &&callback) {
|
||||
_inner->setSendMenuDetails(std::move(callback));
|
||||
}
|
||||
|
||||
bool FieldAutocomplete::eventFilter(QObject *obj, QEvent *e) {
|
||||
|
@ -1364,24 +1365,22 @@ void FieldAutocomplete::Inner::contextMenuEvent(QContextMenuEvent *e) {
|
|||
return;
|
||||
}
|
||||
const auto index = _sel;
|
||||
const auto type = _sendMenuType
|
||||
? _sendMenuType()
|
||||
: SendMenu::Type::Disabled;
|
||||
const auto details = _sendMenuDetails
|
||||
? _sendMenuDetails()
|
||||
: SendMenu::Details();
|
||||
const auto method = FieldAutocomplete::ChooseMethod::ByClick;
|
||||
_menu = base::make_unique_q<Ui::PopupMenu>(
|
||||
this,
|
||||
st::popupMenuWithIcons);
|
||||
|
||||
const auto send = [=](Api::SendOptions options) {
|
||||
const auto send = crl::guard(this, [=](Api::SendOptions options) {
|
||||
chooseAtIndex(method, index, options);
|
||||
};
|
||||
});
|
||||
SendMenu::FillSendMenu(
|
||||
_menu,
|
||||
type,
|
||||
SendMenu::DefaultSilentCallback(send),
|
||||
SendMenu::DefaultScheduleCallback(_show, type, send),
|
||||
SendMenu::DefaultWhenOnlineCallback(send));
|
||||
|
||||
_show,
|
||||
details,
|
||||
SendMenu::DefaultCallback(_show, send));
|
||||
if (!_menu->empty()) {
|
||||
_menu->popup(QCursor::pos());
|
||||
}
|
||||
|
@ -1604,9 +1603,9 @@ void FieldAutocomplete::Inner::showPreview() {
|
|||
}
|
||||
}
|
||||
|
||||
void FieldAutocomplete::Inner::setSendMenuType(
|
||||
Fn<SendMenu::Type()> &&callback) {
|
||||
_sendMenuType = std::move(callback);
|
||||
void FieldAutocomplete::Inner::setSendMenuDetails(
|
||||
Fn<SendMenu::Details()> &&callback) {
|
||||
_sendMenuDetails = std::move(callback);
|
||||
}
|
||||
|
||||
auto FieldAutocomplete::Inner::mentionChosen() const
|
||||
|
|
|
@ -42,7 +42,7 @@ class DocumentMedia;
|
|||
} // namespace Data
|
||||
|
||||
namespace SendMenu {
|
||||
enum class Type;
|
||||
struct Details;
|
||||
} // namespace SendMenu
|
||||
|
||||
namespace ChatHelpers {
|
||||
|
@ -123,7 +123,7 @@ public:
|
|||
void setModerateKeyActivateCallback(Fn<bool(int)> callback) {
|
||||
_moderateKeyActivateCallback = std::move(callback);
|
||||
}
|
||||
void setSendMenuType(Fn<SendMenu::Type()> &&callback);
|
||||
void setSendMenuDetails(Fn<SendMenu::Details()> &&callback);
|
||||
|
||||
void hideFast();
|
||||
void showAnimated();
|
||||
|
|
|
@ -380,22 +380,22 @@ void GifsListWidget::mousePressEvent(QMouseEvent *e) {
|
|||
}
|
||||
|
||||
base::unique_qptr<Ui::PopupMenu> GifsListWidget::fillContextMenu(
|
||||
SendMenu::Type type) {
|
||||
const SendMenu::Details &details) {
|
||||
if (_selected < 0 || _pressed >= 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto menu = base::make_unique_q<Ui::PopupMenu>(this, st().menu);
|
||||
const auto send = [=, selected = _selected](Api::SendOptions options) {
|
||||
const auto selected = _selected;
|
||||
const auto send = crl::guard(this, [=](Api::SendOptions options) {
|
||||
selectInlineResult(selected, options, true);
|
||||
};
|
||||
});
|
||||
const auto icons = &st().icons;
|
||||
SendMenu::FillSendMenu(
|
||||
menu,
|
||||
type,
|
||||
SendMenu::DefaultSilentCallback(send),
|
||||
SendMenu::DefaultScheduleCallback(_show, type, send),
|
||||
SendMenu::DefaultWhenOnlineCallback(send),
|
||||
_show,
|
||||
details,
|
||||
SendMenu::DefaultCallback(_show, send),
|
||||
icons);
|
||||
|
||||
if (const auto item = _mosaic.maybeItemAt(_selected)) {
|
||||
|
|
|
@ -40,7 +40,7 @@ class SessionController;
|
|||
} // namespace Window
|
||||
|
||||
namespace SendMenu {
|
||||
enum class Type;
|
||||
struct Details;
|
||||
} // namespace SendMenu
|
||||
|
||||
namespace Data {
|
||||
|
@ -102,7 +102,7 @@ public:
|
|||
rpl::producer<> cancelRequests() const;
|
||||
|
||||
base::unique_qptr<Ui::PopupMenu> fillContextMenu(
|
||||
SendMenu::Type type) override;
|
||||
const SendMenu::Details &details) override;
|
||||
|
||||
~GifsListWidget();
|
||||
|
||||
|
|
|
@ -1634,7 +1634,7 @@ void StickersListWidget::showStickerSetBox(not_null<DocumentData*> document) {
|
|||
}
|
||||
|
||||
base::unique_qptr<Ui::PopupMenu> StickersListWidget::fillContextMenu(
|
||||
SendMenu::Type type) {
|
||||
const SendMenu::Details &details) {
|
||||
auto selected = _selected;
|
||||
auto &sets = shownSets();
|
||||
if (v::is_null(selected) || !v::is_null(_pressed)) {
|
||||
|
@ -1653,7 +1653,7 @@ base::unique_qptr<Ui::PopupMenu> StickersListWidget::fillContextMenu(
|
|||
auto menu = base::make_unique_q<Ui::PopupMenu>(this, st().menu);
|
||||
|
||||
const auto document = set.stickers[sticker->index].document;
|
||||
const auto send = [=](Api::SendOptions options) {
|
||||
const auto send = crl::guard(this, [=](Api::SendOptions options) {
|
||||
_chosen.fire({
|
||||
.document = document,
|
||||
.options = options,
|
||||
|
@ -1661,14 +1661,13 @@ base::unique_qptr<Ui::PopupMenu> StickersListWidget::fillContextMenu(
|
|||
? Ui::MessageSendingAnimationFrom()
|
||||
: messageSentAnimationInfo(section, index, document),
|
||||
});
|
||||
};
|
||||
});
|
||||
const auto icons = &st().icons;
|
||||
SendMenu::FillSendMenu(
|
||||
menu,
|
||||
type,
|
||||
SendMenu::DefaultSilentCallback(send),
|
||||
SendMenu::DefaultScheduleCallback(_show, type, send),
|
||||
SendMenu::DefaultWhenOnlineCallback(send),
|
||||
_show,
|
||||
details,
|
||||
SendMenu::DefaultCallback(_show, send),
|
||||
icons);
|
||||
|
||||
const auto show = _show;
|
||||
|
|
|
@ -116,7 +116,7 @@ public:
|
|||
std::shared_ptr<Lottie::FrameRenderer> getLottieRenderer();
|
||||
|
||||
base::unique_qptr<Ui::PopupMenu> fillContextMenu(
|
||||
SendMenu::Type type) override;
|
||||
const SendMenu::Details &details) override;
|
||||
|
||||
bool mySetsEmpty() const;
|
||||
|
||||
|
|
|
@ -1297,8 +1297,8 @@ void TabbedSelector::scrollToY(int y) {
|
|||
}
|
||||
}
|
||||
|
||||
void TabbedSelector::showMenuWithType(SendMenu::Type type) {
|
||||
_menu = currentTab()->widget()->fillContextMenu(type);
|
||||
void TabbedSelector::showMenuWithDetails(SendMenu::Details details) {
|
||||
_menu = currentTab()->widget()->fillContextMenu(details);
|
||||
if (_menu && !_menu->empty()) {
|
||||
_menu->popup(QCursor::pos());
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ class TabbedSearch;
|
|||
} // namespace Ui
|
||||
|
||||
namespace SendMenu {
|
||||
enum class Type;
|
||||
struct Details;
|
||||
} // namespace SendMenu
|
||||
|
||||
namespace style {
|
||||
|
@ -178,7 +178,7 @@ public:
|
|||
_beforeHidingCallback = std::move(callback);
|
||||
}
|
||||
|
||||
void showMenuWithType(SendMenu::Type type);
|
||||
void showMenuWithDetails(SendMenu::Details details);
|
||||
void setDropDown(bool dropDown);
|
||||
|
||||
// Float player interface.
|
||||
|
@ -380,7 +380,7 @@ public:
|
|||
virtual void beforeHiding() {
|
||||
}
|
||||
[[nodiscard]] virtual base::unique_qptr<Ui::PopupMenu> fillContextMenu(
|
||||
SendMenu::Type type) {
|
||||
const SendMenu::Details &details) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
|
|
@ -1297,9 +1297,10 @@ std::optional<Reaction> Reactions::parse(const MTPAvailableEffect &entry) {
|
|||
return std::nullopt;
|
||||
}
|
||||
const auto id = DocumentId(data.vid().v);
|
||||
const auto document = _owner->document(id);
|
||||
const auto stickerId = data.veffect_sticker_id().v;
|
||||
const auto document = _owner->document(stickerId);
|
||||
if (!document->sticker()) {
|
||||
LOG(("API Error: Bad sticker in effects: %1").arg(id));
|
||||
LOG(("API Error: Bad sticker in effects: %1").arg(stickerId));
|
||||
return std::nullopt;
|
||||
}
|
||||
const auto aroundId = data.veffect_animation_id().value_or_empty();
|
||||
|
|
|
@ -321,14 +321,22 @@ HistoryWidget::HistoryWidget(
|
|||
_fieldBarCancel->addClickHandler([=] { cancelFieldAreaState(); });
|
||||
_send->addClickHandler([=] { sendButtonClicked(); });
|
||||
|
||||
SendMenu::SetupMenuAndShortcuts(
|
||||
_send.get(),
|
||||
controller->uiShow(),
|
||||
[=] { return sendButtonMenuType(); },
|
||||
[=] { sendSilent(); },
|
||||
[=] { sendScheduled(); },
|
||||
[=] { sendWhenOnline(); });
|
||||
|
||||
{
|
||||
using namespace SendMenu;
|
||||
const auto sendAction = [=](Action action, Details) {
|
||||
const auto options = std::get_if<Api::SendOptions>(&action);
|
||||
if (options || v::get<ActionType>(action) == ActionType::Send) {
|
||||
send(options ? *options : Api::SendOptions());
|
||||
} else {
|
||||
sendScheduled();
|
||||
}
|
||||
};
|
||||
SetupMenuAndShortcuts(
|
||||
_send.get(),
|
||||
controller->uiShow(),
|
||||
[=] { return sendButtonMenuDetails(); },
|
||||
sendAction);
|
||||
}
|
||||
_unblock->addClickHandler([=] { unblockUser(); });
|
||||
_botStart->addClickHandler([=] { sendBotStartCommand(); });
|
||||
_joinChannel->addClickHandler([=] { joinChannel(); });
|
||||
|
@ -514,7 +522,9 @@ HistoryWidget::HistoryWidget(
|
|||
}
|
||||
}, lifetime());
|
||||
|
||||
_fieldAutocomplete->setSendMenuType([=] { return sendMenuType(); });
|
||||
_fieldAutocomplete->setSendMenuDetails([=] {
|
||||
return sendMenuDetails();
|
||||
});
|
||||
|
||||
if (_supportAutocomplete) {
|
||||
supportInitAutocomplete();
|
||||
|
@ -1185,7 +1195,7 @@ void HistoryWidget::initTabbedSelector() {
|
|||
|
||||
selector->contextMenuRequested(
|
||||
) | filter | rpl::start_with_next([=] {
|
||||
selector->showMenuWithType(sendMenuType());
|
||||
selector->showMenuWithDetails(sendMenuDetails());
|
||||
}, lifetime());
|
||||
|
||||
selector->choosingStickerUpdated(
|
||||
|
@ -1564,7 +1574,9 @@ void HistoryWidget::applyInlineBotQuery(UserData *bot, const QString &query) {
|
|||
sendInlineResult(result);
|
||||
}
|
||||
});
|
||||
_inlineResults->setSendMenuType([=] { return sendMenuType(); });
|
||||
_inlineResults->setSendMenuDetails([=] {
|
||||
return sendMenuDetails();
|
||||
});
|
||||
_inlineResults->requesting(
|
||||
) | rpl::start_with_next([=](bool requesting) {
|
||||
_tabbedSelectorToggle->setLoading(requesting);
|
||||
|
@ -4177,10 +4189,6 @@ void HistoryWidget::sendWithModifiers(Qt::KeyboardModifiers modifiers) {
|
|||
send({ .handleSupportSwitch = Support::HandleSwitch(modifiers) });
|
||||
}
|
||||
|
||||
void HistoryWidget::sendSilent() {
|
||||
send({ .silent = true });
|
||||
}
|
||||
|
||||
void HistoryWidget::sendScheduled() {
|
||||
if (!_list) {
|
||||
return;
|
||||
|
@ -4196,22 +4204,20 @@ void HistoryWidget::sendScheduled() {
|
|||
HistoryView::PrepareScheduleBox(
|
||||
_list,
|
||||
controller()->uiShow(),
|
||||
sendMenuType(),
|
||||
sendMenuDetails(),
|
||||
callback));
|
||||
}
|
||||
|
||||
void HistoryWidget::sendWhenOnline() {
|
||||
send(Api::DefaultSendWhenOnlineOptions());
|
||||
}
|
||||
|
||||
SendMenu::Type HistoryWidget::sendMenuType() const {
|
||||
return !_peer
|
||||
SendMenu::Details HistoryWidget::sendMenuDetails() const {
|
||||
const auto type = !_peer
|
||||
? SendMenu::Type::Disabled
|
||||
: _peer->isSelf()
|
||||
? SendMenu::Type::Reminder
|
||||
: HistoryView::CanScheduleUntilOnline(_peer)
|
||||
? SendMenu::Type::ScheduledToUser
|
||||
: SendMenu::Type::Scheduled;
|
||||
const auto effectAllowed = _peer && _peer->isUser();
|
||||
return { .type = type, .effectAllowed = effectAllowed };
|
||||
}
|
||||
|
||||
auto HistoryWidget::computeSendButtonType() const {
|
||||
|
@ -4227,10 +4233,11 @@ auto HistoryWidget::computeSendButtonType() const {
|
|||
return Type::Send;
|
||||
}
|
||||
|
||||
SendMenu::Type HistoryWidget::sendButtonMenuType() const {
|
||||
return (computeSendButtonType() == Ui::SendButton::Type::Send)
|
||||
? sendMenuType()
|
||||
: SendMenu::Type::Disabled;
|
||||
SendMenu::Details HistoryWidget::sendButtonMenuDetails() const {
|
||||
if (computeSendButtonType() != Ui::SendButton::Type::Send) {
|
||||
return {};
|
||||
}
|
||||
return sendMenuDetails();
|
||||
}
|
||||
|
||||
void HistoryWidget::unblockUser() {
|
||||
|
@ -5609,7 +5616,7 @@ bool HistoryWidget::confirmSendingFiles(
|
|||
text,
|
||||
_peer,
|
||||
Api::SendType::Normal,
|
||||
sendMenuType());
|
||||
sendMenuDetails());
|
||||
_field->setTextWithTags({});
|
||||
box->setConfirmedCallback(crl::guard(this, [=](
|
||||
Ui::PreparedList &&list,
|
||||
|
|
|
@ -33,7 +33,7 @@ class PhotoMedia;
|
|||
} // namespace Data
|
||||
|
||||
namespace SendMenu {
|
||||
enum class Type;
|
||||
struct Details;
|
||||
} // namespace SendMenu
|
||||
|
||||
namespace Api {
|
||||
|
@ -268,7 +268,7 @@ public:
|
|||
void confirmDeleteSelected();
|
||||
void clearSelected();
|
||||
|
||||
[[nodiscard]] SendMenu::Type sendMenuType() const;
|
||||
[[nodiscard]] SendMenu::Details sendMenuDetails() const;
|
||||
bool sendExistingDocument(
|
||||
not_null<DocumentData*> document,
|
||||
Api::SendOptions options,
|
||||
|
@ -395,10 +395,8 @@ private:
|
|||
Api::SendOptions options) const;
|
||||
void send(Api::SendOptions options);
|
||||
void sendWithModifiers(Qt::KeyboardModifiers modifiers);
|
||||
void sendSilent();
|
||||
void sendScheduled();
|
||||
void sendWhenOnline();
|
||||
[[nodiscard]] SendMenu::Type sendButtonMenuType() const;
|
||||
[[nodiscard]] SendMenu::Details sendButtonMenuDetails() const;
|
||||
void handlePendingHistoryUpdate();
|
||||
void fullInfoUpdated();
|
||||
void toggleTabbedSelectorMode();
|
||||
|
|
|
@ -854,7 +854,7 @@ ComposeControls::ComposeControls(
|
|||
.recorderHeight = st::historySendSize.height(),
|
||||
.lockFromBottom = descriptor.voiceLockFromBottom,
|
||||
}))
|
||||
, _sendMenuType(descriptor.sendMenuType)
|
||||
, _sendMenuDetails(descriptor.sendMenuDetails)
|
||||
, _unavailableEmojiPasted(std::move(descriptor.unavailableEmojiPasted))
|
||||
, _saveDraftTimer([=] { saveDraft(); })
|
||||
, _saveCloudDraftTimer([=] { saveCloudDraft(); }) {
|
||||
|
@ -1719,7 +1719,7 @@ void ComposeControls::initAutocomplete() {
|
|||
}
|
||||
}, _autocomplete->lifetime());
|
||||
|
||||
_autocomplete->setSendMenuType([=] { return sendMenuType(); });
|
||||
_autocomplete->setSendMenuDetails([=] { return sendMenuDetails(); });
|
||||
|
||||
//_autocomplete->setModerateKeyActivateCallback([=](int key) {
|
||||
// return _keyboard->isHidden()
|
||||
|
@ -2162,7 +2162,7 @@ void ComposeControls::initTabbedSelector() {
|
|||
|
||||
_selector->contextMenuRequested(
|
||||
) | rpl::start_with_next([=] {
|
||||
_selector->showMenuWithType(sendMenuType());
|
||||
_selector->showMenuWithDetails(sendMenuDetails());
|
||||
}, wrap->lifetime());
|
||||
|
||||
_selector->choosingStickerUpdated(
|
||||
|
@ -2191,17 +2191,15 @@ void ComposeControls::initSendButton() {
|
|||
cancelInlineBot();
|
||||
}, _send->lifetime());
|
||||
|
||||
const auto send = [=](Api::SendOptions options) {
|
||||
const auto send = crl::guard(_send.get(), [=](Api::SendOptions options) {
|
||||
_sendCustomRequests.fire(std::move(options));
|
||||
};
|
||||
});
|
||||
|
||||
SendMenu::SetupMenuAndShortcuts(
|
||||
_send.get(),
|
||||
_show,
|
||||
[=] { return sendButtonMenuType(); },
|
||||
SendMenu::DefaultSilentCallback(send),
|
||||
SendMenu::DefaultScheduleCallback(_show, sendMenuType(), send),
|
||||
SendMenu::DefaultWhenOnlineCallback(send));
|
||||
[=] { return sendButtonMenuDetails(); },
|
||||
SendMenu::DefaultCallback(_show, send));
|
||||
}
|
||||
|
||||
void ComposeControls::initSendAsButton(not_null<PeerData*> peer) {
|
||||
|
@ -2510,14 +2508,14 @@ auto ComposeControls::computeSendButtonType() const {
|
|||
return (_mode == Mode::Normal) ? Type::Send : Type::Schedule;
|
||||
}
|
||||
|
||||
SendMenu::Type ComposeControls::sendMenuType() const {
|
||||
return !_history ? SendMenu::Type::Disabled : _sendMenuType;
|
||||
SendMenu::Details ComposeControls::sendMenuDetails() const {
|
||||
return !_history ? SendMenu::Details() : _sendMenuDetails();
|
||||
}
|
||||
|
||||
SendMenu::Type ComposeControls::sendButtonMenuType() const {
|
||||
SendMenu::Details ComposeControls::sendButtonMenuDetails() const {
|
||||
return (computeSendButtonType() == Ui::SendButton::Type::Send)
|
||||
? sendMenuType()
|
||||
: SendMenu::Type::Disabled;
|
||||
? sendMenuDetails()
|
||||
: SendMenu::Details();
|
||||
}
|
||||
|
||||
void ComposeControls::updateSendButtonType() {
|
||||
|
@ -3325,7 +3323,9 @@ void ComposeControls::applyInlineBotQuery(
|
|||
_inlineResultChosen.fire_copy(result);
|
||||
}
|
||||
});
|
||||
_inlineResults->setSendMenuType([=] { return sendMenuType(); });
|
||||
_inlineResults->setSendMenuDetails([=] {
|
||||
return sendMenuDetails();
|
||||
});
|
||||
_inlineResults->requesting(
|
||||
) | rpl::start_with_next([=](bool requesting) {
|
||||
_tabbedSelectorToggle->setLoading(requesting);
|
||||
|
|
|
@ -29,7 +29,7 @@ struct ComposeControls;
|
|||
} // namespace style
|
||||
|
||||
namespace SendMenu {
|
||||
enum class Type;
|
||||
struct Details;
|
||||
} // namespace SendMenu
|
||||
|
||||
namespace ChatHelpers {
|
||||
|
@ -104,7 +104,7 @@ struct ComposeControlsDescriptor {
|
|||
std::shared_ptr<ChatHelpers::Show> show;
|
||||
Fn<void(not_null<DocumentData*>)> unavailableEmojiPasted;
|
||||
ComposeControlsMode mode = ComposeControlsMode::Normal;
|
||||
SendMenu::Type sendMenuType = {};
|
||||
Fn<SendMenu::Details()> sendMenuDetails = nullptr;
|
||||
Window::SessionController *regularWindow = nullptr;
|
||||
rpl::producer<ChatHelpers::FileChosen> stickerOrEmojiChosen;
|
||||
rpl::producer<QString> customPlaceholder;
|
||||
|
@ -282,8 +282,8 @@ private:
|
|||
void paintBackground(QPainter &p, QRect full, QRect clip);
|
||||
|
||||
[[nodiscard]] auto computeSendButtonType() const;
|
||||
[[nodiscard]] SendMenu::Type sendMenuType() const;
|
||||
[[nodiscard]] SendMenu::Type sendButtonMenuType() const;
|
||||
[[nodiscard]] SendMenu::Details sendMenuDetails() const;
|
||||
[[nodiscard]] SendMenu::Details sendButtonMenuDetails() const;
|
||||
|
||||
[[nodiscard]] auto sendContentRequests(
|
||||
SendRequestType requestType = SendRequestType::Text) const;
|
||||
|
@ -396,7 +396,7 @@ private:
|
|||
const std::unique_ptr<FieldHeader> _header;
|
||||
const std::unique_ptr<Controls::VoiceRecordBar> _voiceRecordBar;
|
||||
|
||||
const SendMenu::Type _sendMenuType;
|
||||
const Fn<SendMenu::Details()> _sendMenuDetails;
|
||||
const Fn<void(not_null<DocumentData*>)> _unavailableEmojiPasted;
|
||||
|
||||
rpl::event_stream<Api::SendOptions> _sendCustomRequests;
|
||||
|
|
|
@ -590,7 +590,7 @@ bool AddRescheduleAction(
|
|||
HistoryView::PrepareScheduleBox(
|
||||
&request.navigation->session(),
|
||||
request.navigation->uiShow(),
|
||||
sendMenuType,
|
||||
{ .type = sendMenuType, .effectAllowed = false },
|
||||
callback,
|
||||
date));
|
||||
|
||||
|
|
|
@ -224,9 +224,11 @@ RepliesWidget::RepliesWidget(
|
|||
listShowPremiumToast(emoji);
|
||||
},
|
||||
.mode = ComposeControls::Mode::Normal,
|
||||
.sendMenuType = _topic
|
||||
? SendMenu::Type::Scheduled
|
||||
: SendMenu::Type::SilentOnly,
|
||||
.sendMenuDetails = [=] {
|
||||
using Type = SendMenu::Type;
|
||||
const auto type = _topic ? Type::Scheduled : Type::SilentOnly;
|
||||
return SendMenu::Details{ .type = type };
|
||||
},
|
||||
.regularWindow = controller,
|
||||
.stickerOrEmojiChosen = controller->stickerOrEmojiChosen(),
|
||||
.scheduledToggleValue = _topic
|
||||
|
@ -950,7 +952,7 @@ bool RepliesWidget::confirmSendingFiles(
|
|||
_composeControls->getTextWithAppliedMarkdown(),
|
||||
_history->peer,
|
||||
Api::SendType::Normal,
|
||||
SendMenu::Type::SilentOnly); // #TODO replies schedule
|
||||
SendMenu::Details{ SendMenu::Type::SilentOnly }); // #TODO replies schedule
|
||||
|
||||
box->setConfirmedCallback(crl::guard(this, [=](
|
||||
Ui::PreparedList &&list,
|
||||
|
@ -1445,13 +1447,14 @@ void RepliesWidget::sendInlineResult(
|
|||
finishSending();
|
||||
}
|
||||
|
||||
SendMenu::Type RepliesWidget::sendMenuType() const {
|
||||
SendMenu::Details RepliesWidget::sendMenuDetails() const {
|
||||
// #TODO replies schedule
|
||||
return _history->peer->isSelf()
|
||||
const auto type = _history->peer->isSelf()
|
||||
? SendMenu::Type::Reminder
|
||||
: HistoryView::CanScheduleUntilOnline(_history->peer)
|
||||
? SendMenu::Type::ScheduledToUser
|
||||
: SendMenu::Type::Scheduled;
|
||||
return { .type = type, .effectAllowed = _history->peer->isUser() };
|
||||
}
|
||||
|
||||
FullReplyTo RepliesWidget::replyTo() const {
|
||||
|
|
|
@ -19,7 +19,7 @@ enum class SendMediaType;
|
|||
struct SendingAlbum;
|
||||
|
||||
namespace SendMenu {
|
||||
enum class Type;
|
||||
struct Details;
|
||||
} // namespace SendMenu
|
||||
|
||||
namespace Api {
|
||||
|
@ -249,7 +249,7 @@ private:
|
|||
mtpRequestId *const saveEditMsgRequestId,
|
||||
std::optional<bool> spoilerMediaOverride);
|
||||
void chooseAttach(std::optional<bool> overrideSendImagesAsPhotos);
|
||||
[[nodiscard]] SendMenu::Type sendMenuType() const;
|
||||
[[nodiscard]] SendMenu::Details sendMenuDetails() const;
|
||||
[[nodiscard]] FullReplyTo replyTo() const;
|
||||
[[nodiscard]] HistoryItem *lookupRoot() const;
|
||||
[[nodiscard]] Data::ForumTopic *lookupTopic();
|
||||
|
|
|
@ -70,7 +70,7 @@ bool CanScheduleUntilOnline(not_null<PeerData*> peer) {
|
|||
void ScheduleBox(
|
||||
not_null<Ui::GenericBox*> box,
|
||||
std::shared_ptr<ChatHelpers::Show> show,
|
||||
SendMenu::Type type,
|
||||
const SendMenu::Details &details,
|
||||
Fn<void(Api::SendOptions)> done,
|
||||
TimeId time,
|
||||
ScheduleBoxStyleArgs style) {
|
||||
|
@ -87,7 +87,7 @@ void ScheduleBox(
|
|||
copy(result);
|
||||
};
|
||||
auto descriptor = Ui::ChooseDateTimeBox(box, {
|
||||
.title = (type == SendMenu::Type::Reminder
|
||||
.title = (details.type == SendMenu::Type::Reminder
|
||||
? tr::lng_remind_title()
|
||||
: tr::lng_schedule_title()),
|
||||
.submit = tr::lng_schedule_button(),
|
||||
|
@ -96,16 +96,26 @@ void ScheduleBox(
|
|||
.style = style.chooseDateTimeArgs,
|
||||
});
|
||||
|
||||
using T = SendMenu::Type;
|
||||
SendMenu::SetupMenuAndShortcuts(
|
||||
using namespace SendMenu;
|
||||
const auto childType = (details.type == Type::Disabled)
|
||||
? Type::Disabled
|
||||
: Type::SilentOnly;
|
||||
const auto childDetails = Details{
|
||||
.type = childType,
|
||||
.effectAllowed = details.effectAllowed,
|
||||
};
|
||||
const auto sendAction = crl::guard(box, [=](Action action, Details) {
|
||||
save(
|
||||
v::get<Api::SendOptions>(action).silent,
|
||||
descriptor.collect());
|
||||
});
|
||||
SetupMenuAndShortcuts(
|
||||
descriptor.submit.data(),
|
||||
show,
|
||||
[t = type == T::Disabled ? T::Disabled : T::SilentOnly] { return t; },
|
||||
[=] { save(true, descriptor.collect()); },
|
||||
nullptr,
|
||||
nullptr);
|
||||
[=] { return childDetails; },
|
||||
sendAction);
|
||||
|
||||
if (type == SendMenu::Type::ScheduledToUser) {
|
||||
if (details.type == Type::ScheduledToUser) {
|
||||
const auto sendUntilOnline = box->addTopButton(*style.topButtonStyle);
|
||||
const auto timestamp = Api::kScheduledUntilOnlineTimestamp;
|
||||
FillSendUntilOnlineMenu(
|
||||
|
|
|
@ -23,7 +23,7 @@ class Show;
|
|||
} // namespace ChatHelpers
|
||||
|
||||
namespace SendMenu {
|
||||
enum class Type;
|
||||
struct Details;
|
||||
} // namespace SendMenu
|
||||
|
||||
namespace HistoryView {
|
||||
|
@ -41,7 +41,7 @@ struct ScheduleBoxStyleArgs {
|
|||
void ScheduleBox(
|
||||
not_null<Ui::GenericBox*> box,
|
||||
std::shared_ptr<ChatHelpers::Show> show,
|
||||
SendMenu::Type type,
|
||||
const SendMenu::Details &details,
|
||||
Fn<void(Api::SendOptions)> done,
|
||||
TimeId time,
|
||||
ScheduleBoxStyleArgs style);
|
||||
|
@ -50,14 +50,14 @@ template <typename Guard, typename Submit>
|
|||
[[nodiscard]] object_ptr<Ui::GenericBox> PrepareScheduleBox(
|
||||
Guard &&guard,
|
||||
std::shared_ptr<ChatHelpers::Show> show,
|
||||
SendMenu::Type type,
|
||||
const SendMenu::Details &details,
|
||||
Submit &&submit,
|
||||
TimeId scheduleTime = DefaultScheduleTime(),
|
||||
ScheduleBoxStyleArgs style = ScheduleBoxStyleArgs()) {
|
||||
return Box(
|
||||
ScheduleBox,
|
||||
std::move(show),
|
||||
type,
|
||||
details,
|
||||
crl::guard(std::forward<Guard>(guard), std::forward<Submit>(submit)),
|
||||
scheduleTime,
|
||||
std::move(style));
|
||||
|
|
|
@ -115,7 +115,7 @@ ScheduledWidget::ScheduledWidget(
|
|||
listShowPremiumToast(emoji);
|
||||
},
|
||||
.mode = ComposeControls::Mode::Scheduled,
|
||||
.sendMenuType = SendMenu::Type::Disabled,
|
||||
.sendMenuDetails = [] { return SendMenu::Details(); },
|
||||
.regularWindow = controller,
|
||||
.stickerOrEmojiChosen = controller->stickerOrEmojiChosen(),
|
||||
}))
|
||||
|
@ -493,7 +493,7 @@ bool ScheduledWidget::confirmSendingFiles(
|
|||
(CanScheduleUntilOnline(_history->peer)
|
||||
? Api::SendType::ScheduledToUser
|
||||
: Api::SendType::Scheduled),
|
||||
SendMenu::Type::Disabled);
|
||||
SendMenu::Details());
|
||||
|
||||
box->setConfirmedCallback(crl::guard(this, [=](
|
||||
Ui::PreparedList &&list,
|
||||
|
@ -602,7 +602,7 @@ void ScheduledWidget::uploadFile(
|
|||
prepareSendAction(options));
|
||||
};
|
||||
controller()->show(
|
||||
PrepareScheduleBox(this, _show, sendMenuType(), callback));
|
||||
PrepareScheduleBox(this, _show, sendMenuDetails(), callback));
|
||||
}
|
||||
|
||||
bool ScheduledWidget::showSendingFilesError(
|
||||
|
@ -681,7 +681,7 @@ void ScheduledWidget::send() {
|
|||
}
|
||||
const auto callback = [=](Api::SendOptions options) { send(options); };
|
||||
controller()->show(
|
||||
PrepareScheduleBox(this, _show, sendMenuType(), callback));
|
||||
PrepareScheduleBox(this, _show, sendMenuDetails(), callback));
|
||||
}
|
||||
|
||||
void ScheduledWidget::send(Api::SendOptions options) {
|
||||
|
@ -713,7 +713,7 @@ void ScheduledWidget::sendVoice(
|
|||
sendVoice(bytes, waveform, duration, options);
|
||||
};
|
||||
controller()->show(
|
||||
PrepareScheduleBox(this, _show, sendMenuType(), callback));
|
||||
PrepareScheduleBox(this, _show, sendMenuDetails(), callback));
|
||||
}
|
||||
|
||||
void ScheduledWidget::sendVoice(
|
||||
|
@ -814,7 +814,7 @@ void ScheduledWidget::sendExistingDocument(
|
|||
sendExistingDocument(document, options);
|
||||
};
|
||||
controller()->show(
|
||||
PrepareScheduleBox(this, _show, sendMenuType(), callback));
|
||||
PrepareScheduleBox(this, _show, sendMenuDetails(), callback));
|
||||
}
|
||||
|
||||
bool ScheduledWidget::sendExistingDocument(
|
||||
|
@ -844,7 +844,7 @@ void ScheduledWidget::sendExistingPhoto(not_null<PhotoData*> photo) {
|
|||
sendExistingPhoto(photo, options);
|
||||
};
|
||||
controller()->show(
|
||||
PrepareScheduleBox(this, _show, sendMenuType(), callback));
|
||||
PrepareScheduleBox(this, _show, sendMenuDetails(), callback));
|
||||
}
|
||||
|
||||
bool ScheduledWidget::sendExistingPhoto(
|
||||
|
@ -879,7 +879,7 @@ void ScheduledWidget::sendInlineResult(
|
|||
sendInlineResult(result, bot, options);
|
||||
};
|
||||
controller()->show(
|
||||
PrepareScheduleBox(this, _show, sendMenuType(), callback));
|
||||
PrepareScheduleBox(this, _show, sendMenuDetails(), callback));
|
||||
}
|
||||
|
||||
void ScheduledWidget::sendInlineResult(
|
||||
|
@ -911,12 +911,14 @@ void ScheduledWidget::sendInlineResult(
|
|||
_composeControls->focus();
|
||||
}
|
||||
|
||||
SendMenu::Type ScheduledWidget::sendMenuType() const {
|
||||
return _history->peer->isSelf()
|
||||
SendMenu::Details ScheduledWidget::sendMenuDetails() const {
|
||||
const auto type = _history->peer->isSelf()
|
||||
? SendMenu::Type::Reminder
|
||||
: HistoryView::CanScheduleUntilOnline(_history->peer)
|
||||
? SendMenu::Type::ScheduledToUser
|
||||
: SendMenu::Type::Scheduled;
|
||||
const auto effectAllowed = _history->peer->isUser();
|
||||
return { .type = type, .effectAllowed = effectAllowed };
|
||||
}
|
||||
|
||||
void ScheduledWidget::cornerButtonsShowAtPosition(
|
||||
|
@ -1368,7 +1370,7 @@ void ScheduledWidget::listSendBotCommand(
|
|||
session().api().sendMessage(std::move(message));
|
||||
};
|
||||
controller()->show(
|
||||
PrepareScheduleBox(this, _show, sendMenuType(), callback));
|
||||
PrepareScheduleBox(this, _show, sendMenuDetails(), callback));
|
||||
}
|
||||
|
||||
void ScheduledWidget::listSearch(
|
||||
|
|
|
@ -22,7 +22,7 @@ class Show;
|
|||
} // namespace ChatHelpers
|
||||
|
||||
namespace SendMenu {
|
||||
enum class Type;
|
||||
struct Details;
|
||||
} // namespace SendMenu
|
||||
|
||||
namespace Api {
|
||||
|
@ -221,7 +221,7 @@ private:
|
|||
std::optional<bool> spoilerMediaOverride);
|
||||
void highlightSingleNewMessage(const Data::MessagesSlice &slice);
|
||||
void chooseAttach();
|
||||
[[nodiscard]] SendMenu::Type sendMenuType() const;
|
||||
[[nodiscard]] SendMenu::Details sendMenuDetails() const;
|
||||
|
||||
void pushReplyReturn(not_null<HistoryItem*> item);
|
||||
void checkReplyReturns();
|
||||
|
|
|
@ -23,6 +23,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "data/stickers/data_custom_emoji.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "main/main_session.h"
|
||||
#include "menu/menu_send.h"
|
||||
#include "chat_helpers/emoji_list_widget.h"
|
||||
#include "chat_helpers/stickers_list_footer.h"
|
||||
#include "window/window_session_controller.h"
|
||||
|
@ -123,15 +124,11 @@ UnifiedFactoryOwner::UnifiedFactoryOwner(
|
|||
const auto inStrip = _strip ? _strip->count() : 0;
|
||||
_unifiedIdsList.reserve(reactions.size());
|
||||
for (const auto &reaction : reactions) {
|
||||
if (const auto id = reaction.id.custom()) {
|
||||
_unifiedIdsList.push_back(id);
|
||||
} else {
|
||||
_unifiedIdsList.push_back(reaction.selectAnimation->id);
|
||||
}
|
||||
_unifiedIdsList.push_back(reaction.selectAnimation->id);
|
||||
|
||||
const auto unifiedId = _unifiedIdsList.back();
|
||||
if (!reaction.id.custom()) {
|
||||
_defaultReactionIds.emplace(unifiedId, reaction.id.emoji());
|
||||
if (unifiedId != reaction.id.custom()) {
|
||||
_defaultReactionIds.emplace(unifiedId, reaction.id);
|
||||
}
|
||||
if (index + 1 < inStrip) {
|
||||
_defaultReactionInStripMap.emplace(unifiedId, index++);
|
||||
|
@ -165,7 +162,7 @@ Data::ReactionId UnifiedFactoryOwner::lookupReactionId(
|
|||
DocumentId unifiedId) const {
|
||||
const auto i = _defaultReactionIds.find(unifiedId);
|
||||
return (i != end(_defaultReactionIds))
|
||||
? Data::ReactionId{ i->second }
|
||||
? i->second
|
||||
: Data::ReactionId{ unifiedId };
|
||||
}
|
||||
|
||||
|
@ -174,21 +171,23 @@ UnifiedFactoryOwner::RecentFactory UnifiedFactoryOwner::factory() {
|
|||
-> std::unique_ptr<Ui::Text::CustomEmoji> {
|
||||
const auto tag = Data::CustomEmojiManager::SizeTag::Large;
|
||||
const auto sizeOverride = st::reactStripImage;
|
||||
const auto isDefaultReaction = _defaultReactionIds.contains(id);
|
||||
const auto i = _defaultReactionIds.find(id);
|
||||
const auto isDefaultReaction = (i != end(_defaultReactionIds))
|
||||
&& !i->second.custom();
|
||||
const auto manager = &_session->data().customEmojiManager();
|
||||
auto result = isDefaultReaction
|
||||
? std::make_unique<Ui::Text::ShiftedEmoji>(
|
||||
manager->create(id, std::move(repaint), tag, sizeOverride),
|
||||
_defaultReactionShift)
|
||||
: manager->create(id, std::move(repaint), tag);
|
||||
const auto i = _defaultReactionInStripMap.find(id);
|
||||
if (i != end(_defaultReactionInStripMap)) {
|
||||
const auto j = _defaultReactionInStripMap.find(id);
|
||||
if (j != end(_defaultReactionInStripMap)) {
|
||||
Assert(_strip != nullptr);
|
||||
return std::make_unique<StripEmoji>(
|
||||
std::move(result),
|
||||
_strip,
|
||||
-_stripPaintOneShift,
|
||||
i->second);
|
||||
j->second);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
|
|
@ -66,7 +66,7 @@ private:
|
|||
Strip *_strip = nullptr;
|
||||
|
||||
std::vector<DocumentId> _unifiedIdsList;
|
||||
base::flat_map<DocumentId, QString> _defaultReactionIds;
|
||||
base::flat_map<DocumentId, Data::ReactionId> _defaultReactionIds;
|
||||
base::flat_map<DocumentId, int> _defaultReactionInStripMap;
|
||||
|
||||
QPoint _defaultReactionShift;
|
||||
|
|
|
@ -229,7 +229,7 @@ void EmojiStatusPanel::create(const Descriptor &descriptor) {
|
|||
|
||||
_panel->selector()->contextMenuRequested(
|
||||
) | rpl::start_with_next([=] {
|
||||
_panel->selector()->showMenuWithType(SendMenu::Type::Scheduled);
|
||||
_panel->selector()->showMenuWithDetails({});
|
||||
}, _panel->lifetime());
|
||||
|
||||
auto statusChosen = _panel->selector()->customEmojiChosen(
|
||||
|
|
|
@ -1703,7 +1703,7 @@ std::unique_ptr<Ui::DropdownMenu> MakeAttachBotsMenu(
|
|||
flag,
|
||||
flag,
|
||||
source,
|
||||
sendMenuType);
|
||||
{ sendMenuType });
|
||||
}, &st::menuIconCreatePoll);
|
||||
}
|
||||
for (const auto &bot : bots->attachBots()) {
|
||||
|
|
|
@ -329,23 +329,23 @@ void Inner::contextMenuEvent(QContextMenuEvent *e) {
|
|||
if (_selected < 0 || _pressed >= 0) {
|
||||
return;
|
||||
}
|
||||
const auto type = _sendMenuType
|
||||
? _sendMenuType()
|
||||
: SendMenu::Type::Disabled;
|
||||
const auto details = _sendMenuDetails
|
||||
? _sendMenuDetails()
|
||||
: SendMenu::Details();
|
||||
|
||||
_menu = base::make_unique_q<Ui::PopupMenu>(
|
||||
this,
|
||||
st::popupMenuWithIcons);
|
||||
|
||||
const auto send = [=, selected = _selected](Api::SendOptions options) {
|
||||
const auto selected = _selected;
|
||||
const auto send = crl::guard(this, [=](Api::SendOptions options) {
|
||||
selectInlineResult(selected, options, false);
|
||||
};
|
||||
});
|
||||
SendMenu::FillSendMenu(
|
||||
_menu,
|
||||
type,
|
||||
SendMenu::DefaultSilentCallback(send),
|
||||
SendMenu::DefaultScheduleCallback(_controller->uiShow(), type, send),
|
||||
SendMenu::DefaultWhenOnlineCallback(send));
|
||||
_controller->uiShow(),
|
||||
details,
|
||||
SendMenu::DefaultCallback(_controller->uiShow(), send));
|
||||
|
||||
const auto item = _mosaic.itemAt(_selected);
|
||||
if (const auto previewDocument = item->getPreviewDocument()) {
|
||||
|
@ -689,8 +689,8 @@ void Inner::switchPm() {
|
|||
}
|
||||
}
|
||||
|
||||
void Inner::setSendMenuType(Fn<SendMenu::Type()> &&callback) {
|
||||
_sendMenuType = std::move(callback);
|
||||
void Inner::setSendMenuDetails(Fn<SendMenu::Details()> &&callback) {
|
||||
_sendMenuDetails = std::move(callback);
|
||||
}
|
||||
|
||||
} // namespace Layout
|
||||
|
|
|
@ -43,7 +43,7 @@ struct ResultSelected;
|
|||
} // namespace InlineBots
|
||||
|
||||
namespace SendMenu {
|
||||
enum class Type;
|
||||
struct Details;
|
||||
} // namespace SendMenu
|
||||
|
||||
namespace InlineBots {
|
||||
|
@ -89,7 +89,7 @@ public:
|
|||
void setResultSelectedCallback(Fn<void(ResultSelected)> callback) {
|
||||
_resultSelectedCallback = std::move(callback);
|
||||
}
|
||||
void setSendMenuType(Fn<SendMenu::Type()> &&callback);
|
||||
void setSendMenuDetails(Fn<SendMenu::Details()> &&callback);
|
||||
|
||||
// Ui::AbstractTooltipShower interface.
|
||||
QString tooltipText() const override;
|
||||
|
@ -179,7 +179,7 @@ private:
|
|||
bool _previewShown = false;
|
||||
|
||||
Fn<void(ResultSelected)> _resultSelectedCallback;
|
||||
Fn<SendMenu::Type()> _sendMenuType;
|
||||
Fn<SendMenu::Details()> _sendMenuDetails;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -265,8 +265,8 @@ void Widget::setResultSelectedCallback(Fn<void(ResultSelected)> callback) {
|
|||
_inner->setResultSelectedCallback(std::move(callback));
|
||||
}
|
||||
|
||||
void Widget::setSendMenuType(Fn<SendMenu::Type()> &&callback) {
|
||||
_inner->setSendMenuType(std::move(callback));
|
||||
void Widget::setSendMenuDetails(Fn<SendMenu::Details()> &&callback) {
|
||||
_inner->setSendMenuDetails(std::move(callback));
|
||||
}
|
||||
|
||||
void Widget::hideAnimated() {
|
||||
|
|
|
@ -45,7 +45,7 @@ struct ResultSelected;
|
|||
} // namespace InlineBots
|
||||
|
||||
namespace SendMenu {
|
||||
enum class Type;
|
||||
struct Details;
|
||||
} // namespace SendMenu
|
||||
|
||||
namespace InlineBots {
|
||||
|
@ -75,7 +75,7 @@ public:
|
|||
void hideAnimated();
|
||||
|
||||
void setResultSelectedCallback(Fn<void(ResultSelected)> callback);
|
||||
void setSendMenuType(Fn<SendMenu::Type()> &&callback);
|
||||
void setSendMenuDetails(Fn<SendMenu::Details()> &&callback);
|
||||
|
||||
[[nodiscard]] rpl::producer<bool> requesting() const {
|
||||
return _requesting.events();
|
||||
|
|
|
@ -1047,8 +1047,8 @@ void MainWidget::exportTopBarHeightUpdated() {
|
|||
}
|
||||
}
|
||||
|
||||
SendMenu::Type MainWidget::sendMenuType() const {
|
||||
return _history->sendMenuType();
|
||||
SendMenu::Details MainWidget::sendMenuDetails() const {
|
||||
return _history->sendMenuDetails();
|
||||
}
|
||||
|
||||
bool MainWidget::sendExistingDocument(not_null<DocumentData*> document) {
|
||||
|
|
|
@ -29,7 +29,7 @@ struct SendOptions;
|
|||
} // namespace Api
|
||||
|
||||
namespace SendMenu {
|
||||
enum class Type;
|
||||
struct Details;
|
||||
} // namespace SendMenu
|
||||
|
||||
namespace Main {
|
||||
|
@ -157,7 +157,7 @@ public:
|
|||
QPixmap grabForShowAnimation(const Window::SectionSlideParams ¶ms);
|
||||
void checkMainSectionToLayer();
|
||||
|
||||
[[nodiscard]] SendMenu::Type sendMenuType() const;
|
||||
[[nodiscard]] SendMenu::Details sendMenuDetails() const;
|
||||
bool sendExistingDocument(not_null<DocumentData*> document);
|
||||
bool sendExistingDocument(
|
||||
not_null<DocumentData*> document,
|
||||
|
|
|
@ -123,7 +123,7 @@ ReplyArea::ReplyArea(not_null<Controller*> controller)
|
|||
showPremiumToast(emoji);
|
||||
},
|
||||
.mode = HistoryView::ComposeControlsMode::Normal,
|
||||
.sendMenuType = SendMenu::Type::SilentOnly,
|
||||
.sendMenuDetails = sendMenuDetails(),
|
||||
.stickerOrEmojiChosen = _controller->stickerOrEmojiChosen(),
|
||||
.customPlaceholder = PlaceholderText(
|
||||
_controller->uiShow(),
|
||||
|
@ -473,6 +473,15 @@ void ReplyArea::chooseAttach(
|
|||
crl::guard(this, [=] { _choosingAttach = false; }));
|
||||
}
|
||||
|
||||
Fn<SendMenu::Details()> ReplyArea::sendMenuDetails() const {
|
||||
return crl::guard(this, [=] {
|
||||
return SendMenu::Details{
|
||||
.type = SendMenu::Type::SilentOnly,
|
||||
.effectAllowed = _data.peer && _data.peer->isUser(),
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
bool ReplyArea::confirmSendingFiles(
|
||||
not_null<const QMimeData*> data,
|
||||
std::optional<bool> overrideSendImagesAsPhotos,
|
||||
|
@ -528,7 +537,7 @@ bool ReplyArea::confirmSendingFiles(
|
|||
.limits = DefaultLimitsForPeer(_data.peer),
|
||||
.check = DefaultCheckForPeer(show, _data.peer),
|
||||
.sendType = Api::SendType::Normal,
|
||||
.sendMenuType = SendMenu::Type::SilentOnly,
|
||||
.sendMenuDetails = sendMenuDetails(),
|
||||
.stOverride = &st::storiesComposeControls,
|
||||
.confirmed = crl::guard(this, confirmed),
|
||||
.cancelled = _controls->restoreTextCallback(insertTextOnCancel),
|
||||
|
|
|
@ -38,6 +38,10 @@ namespace Main {
|
|||
class Session;
|
||||
} // namespace Main
|
||||
|
||||
namespace SendMenu {
|
||||
struct Details;
|
||||
} // namespace SendMenu
|
||||
|
||||
namespace Ui {
|
||||
struct PreparedList;
|
||||
class SendFilesWay;
|
||||
|
@ -141,6 +145,8 @@ private:
|
|||
void sendVoice(VoiceToSend &&data);
|
||||
void chooseAttach(std::optional<bool> overrideSendImagesAsPhotos);
|
||||
|
||||
[[nodiscard]] Fn<SendMenu::Details()> sendMenuDetails() const;
|
||||
|
||||
void showPremiumToast(not_null<DocumentData*> emoji);
|
||||
[[nodiscard]] bool showSlowmodeError();
|
||||
|
||||
|
|
|
@ -348,8 +348,8 @@ public:
|
|||
rpl::producer<bool> adjustShadowLeft() const override {
|
||||
return rpl::single(false);
|
||||
}
|
||||
SendMenu::Type sendMenuType() const override {
|
||||
return SendMenu::Type::SilentOnly;
|
||||
SendMenu::Details sendMenuDetails() const override {
|
||||
return { SendMenu::Type::SilentOnly };
|
||||
}
|
||||
|
||||
bool showMediaPreview(
|
||||
|
|
|
@ -37,140 +37,121 @@ namespace {
|
|||
not_null<Main::Session*> session) {
|
||||
auto result = Data::PossibleItemReactionsRef();
|
||||
const auto reactions = &session->data().reactions();
|
||||
const auto &full = reactions->list(Data::Reactions::Type::Active);
|
||||
const auto &top = reactions->list(Data::Reactions::Type::Top);
|
||||
const auto &recent = reactions->list(Data::Reactions::Type::Recent);
|
||||
const auto &effects = reactions->list(Data::Reactions::Type::Effects);
|
||||
const auto premiumPossible = session->premiumPossible();
|
||||
auto added = base::flat_set<Data::ReactionId>();
|
||||
result.recent.reserve(full.size());
|
||||
for (const auto &reaction : ranges::views::concat(top, recent, full)) {
|
||||
if (premiumPossible || !reaction.id.custom()) {
|
||||
result.recent.reserve(effects.size());
|
||||
for (const auto &reaction : effects) {
|
||||
if (premiumPossible || !reaction.premium) {
|
||||
if (added.emplace(reaction.id).second) {
|
||||
result.recent.push_back(&reaction);
|
||||
}
|
||||
}
|
||||
}
|
||||
result.customAllowed = premiumPossible;
|
||||
const auto i = ranges::find(
|
||||
result.recent,
|
||||
reactions->favoriteId(),
|
||||
&Data::Reaction::id);
|
||||
if (i != end(result.recent) && i != begin(result.recent)) {
|
||||
std::rotate(begin(result.recent), i, i + 1);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Fn<void()> DefaultSilentCallback(Fn<void(Api::SendOptions)> send) {
|
||||
return [=] { send({ .silent = true }); };
|
||||
}
|
||||
|
||||
Fn<void()> DefaultScheduleCallback(
|
||||
Fn<void(Action, Details)> DefaultCallback(
|
||||
std::shared_ptr<ChatHelpers::Show> show,
|
||||
Type type,
|
||||
Fn<void(Api::SendOptions)> send) {
|
||||
return [=, weak = Ui::MakeWeak(show->toastParent())] {
|
||||
show->showBox(
|
||||
HistoryView::PrepareScheduleBox(
|
||||
weak,
|
||||
show,
|
||||
type,
|
||||
[=](Api::SendOptions options) { send(options); }),
|
||||
Ui::LayerOption::KeepOther);
|
||||
const auto guard = Ui::MakeWeak(show->toastParent());
|
||||
return [=](Action action, Details details) {
|
||||
if (const auto options = std::get_if<Api::SendOptions>(&action)) {
|
||||
send(*options);
|
||||
} else if (v::get<ActionType>(action) == ActionType::Send) {
|
||||
send({});
|
||||
} else {
|
||||
using namespace HistoryView;
|
||||
auto box = PrepareScheduleBox(guard, show, details, send);
|
||||
const auto weak = Ui::MakeWeak(box.data());
|
||||
show->showBox(std::move(box));
|
||||
if (const auto strong = weak.data()) {
|
||||
strong->setCloseByOutsideClick(false);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Fn<void()> DefaultWhenOnlineCallback(Fn<void(Api::SendOptions)> send) {
|
||||
return [=] { send(Api::DefaultSendWhenOnlineOptions()); };
|
||||
}
|
||||
|
||||
FillMenuResult FillSendMenu(
|
||||
not_null<Ui::PopupMenu*> menu,
|
||||
Type type,
|
||||
Fn<void()> silent,
|
||||
Fn<void()> schedule,
|
||||
Fn<void()> whenOnline,
|
||||
const style::ComposeIcons *iconsOverride) {
|
||||
if (!silent && !schedule) {
|
||||
return FillMenuResult::None;
|
||||
std::shared_ptr<ChatHelpers::Show> showForEffect,
|
||||
Details details,
|
||||
Fn<void(Action, Details)> action,
|
||||
const style::ComposeIcons *iconsOverride,
|
||||
std::optional<QPoint> desiredPositionOverride) {
|
||||
const auto type = details.type;
|
||||
if (type == Type::Disabled || !action) {
|
||||
return FillMenuResult::Skipped;
|
||||
}
|
||||
const auto &icons = iconsOverride
|
||||
? *iconsOverride
|
||||
: st::defaultComposeIcons;
|
||||
const auto now = type;
|
||||
if (now == Type::Disabled
|
||||
|| (!silent && now == Type::SilentOnly)) {
|
||||
return FillMenuResult::None;
|
||||
}
|
||||
|
||||
if (silent && now != Type::Reminder) {
|
||||
if (type != Type::Reminder) {
|
||||
menu->addAction(
|
||||
tr::lng_send_silent_message(tr::now),
|
||||
silent,
|
||||
[=] { action(Api::SendOptions{ .silent = true }, details); },
|
||||
&icons.menuMute);
|
||||
}
|
||||
if (schedule && now != Type::SilentOnly) {
|
||||
if (type != Type::SilentOnly) {
|
||||
menu->addAction(
|
||||
(now == Type::Reminder
|
||||
(type == Type::Reminder
|
||||
? tr::lng_reminder_message(tr::now)
|
||||
: tr::lng_schedule_message(tr::now)),
|
||||
schedule,
|
||||
[=] { action(ActionType::Schedule, details); },
|
||||
&icons.menuSchedule);
|
||||
}
|
||||
if (whenOnline && now == Type::ScheduledToUser) {
|
||||
if (type == Type::ScheduledToUser) {
|
||||
menu->addAction(
|
||||
tr::lng_scheduled_send_until_online(tr::now),
|
||||
whenOnline,
|
||||
[=] { action(Api::DefaultSendWhenOnlineOptions(), details); },
|
||||
&icons.menuWhenOnline);
|
||||
}
|
||||
return FillMenuResult::Success;
|
||||
|
||||
using namespace HistoryView::Reactions;
|
||||
const auto position = desiredPositionOverride.value_or(QCursor::pos());
|
||||
const auto selector = (showForEffect && details.effectAllowed)
|
||||
? AttachSelectorToMenu(
|
||||
menu,
|
||||
position,
|
||||
st::reactPanelEmojiPan,
|
||||
showForEffect,
|
||||
LookupPossibleEffects(&showForEffect->session()),
|
||||
{ tr::lng_effect_add_title(tr::now) })
|
||||
: base::make_unexpected(AttachSelectorResult::Skipped);
|
||||
if (!selector) {
|
||||
if (selector.error() == AttachSelectorResult::Failed) {
|
||||
return FillMenuResult::Failed;
|
||||
}
|
||||
menu->prepareGeometryFor(position);
|
||||
return FillMenuResult::Prepared;
|
||||
}
|
||||
|
||||
(*selector)->chosen(
|
||||
) | rpl::start_with_next([=](ChosenReaction chosen) {
|
||||
|
||||
}, menu->lifetime());
|
||||
|
||||
return FillMenuResult::Prepared;
|
||||
}
|
||||
|
||||
void SetupMenuAndShortcuts(
|
||||
not_null<Ui::RpWidget*> button,
|
||||
std::shared_ptr<ChatHelpers::Show> show,
|
||||
Fn<Type()> type,
|
||||
Fn<void()> silent,
|
||||
Fn<void()> schedule,
|
||||
Fn<void()> whenOnline) {
|
||||
if (!silent && !schedule && !whenOnline) {
|
||||
return;
|
||||
}
|
||||
Fn<Details()> details,
|
||||
Fn<void(Action, Details)> action) {
|
||||
const auto menu = std::make_shared<base::unique_qptr<Ui::PopupMenu>>();
|
||||
const auto showMenu = [=] {
|
||||
*menu = base::make_unique_q<Ui::PopupMenu>(
|
||||
button,
|
||||
st::popupMenuWithIcons);
|
||||
const auto result = FillSendMenu(
|
||||
*menu,
|
||||
type(),
|
||||
silent,
|
||||
schedule,
|
||||
whenOnline);
|
||||
if (result != FillMenuResult::Success) {
|
||||
const auto result = FillSendMenu(*menu, show, details(), action);
|
||||
if (result != FillMenuResult::Prepared) {
|
||||
return false;
|
||||
}
|
||||
const auto desiredPosition = QCursor::pos();
|
||||
using namespace HistoryView::Reactions;
|
||||
const auto selector = show
|
||||
? AttachSelectorToMenu(
|
||||
menu->get(),
|
||||
desiredPosition,
|
||||
st::reactPanelEmojiPan,
|
||||
show,
|
||||
LookupPossibleEffects(&show->session()),
|
||||
{ tr::lng_effect_add_title(tr::now) })
|
||||
: base::make_unexpected(AttachSelectorResult::Skipped);
|
||||
if (selector) {
|
||||
//(*selector)->chosen();
|
||||
(*menu)->popupPrepared();
|
||||
} else if (selector.error() == AttachSelectorResult::Failed) {
|
||||
return false;
|
||||
} else {
|
||||
(*menu)->popup(desiredPosition);
|
||||
}
|
||||
(*menu)->popupPrepared();
|
||||
return true;
|
||||
};
|
||||
base::install_event_filter(button, [=](not_null<QEvent*> e) {
|
||||
|
@ -186,24 +167,21 @@ void SetupMenuAndShortcuts(
|
|||
}) | rpl::start_with_next([=](not_null<Shortcuts::Request*> request) {
|
||||
using Command = Shortcuts::Command;
|
||||
|
||||
const auto now = type();
|
||||
if (now == Type::Disabled
|
||||
|| (!silent && now == Type::SilentOnly)) {
|
||||
const auto now = details().type;
|
||||
if (now == Type::Disabled) {
|
||||
return;
|
||||
}
|
||||
(silent
|
||||
&& (now != Type::Reminder)
|
||||
((now != Type::Reminder)
|
||||
&& request->check(Command::SendSilentMessage)
|
||||
&& request->handle([=] {
|
||||
silent();
|
||||
action(Api::SendOptions{ .silent = true }, details());
|
||||
return true;
|
||||
}))
|
||||
||
|
||||
(schedule
|
||||
&& (now != Type::SilentOnly)
|
||||
((now != Type::SilentOnly)
|
||||
&& request->check(Command::ScheduleMessage)
|
||||
&& request->handle([=] {
|
||||
schedule();
|
||||
action(ActionType::Schedule, details());
|
||||
return true;
|
||||
}))
|
||||
||
|
||||
|
|
|
@ -39,33 +39,39 @@ enum class Type {
|
|||
Reminder,
|
||||
};
|
||||
|
||||
enum class FillMenuResult {
|
||||
Success,
|
||||
None,
|
||||
struct Details {
|
||||
Type type = Type::Disabled;
|
||||
bool effectAllowed = false;
|
||||
};
|
||||
|
||||
Fn<void()> DefaultSilentCallback(Fn<void(Api::SendOptions)> send);
|
||||
Fn<void()> DefaultScheduleCallback(
|
||||
enum class FillMenuResult {
|
||||
Prepared,
|
||||
Skipped,
|
||||
Failed,
|
||||
};
|
||||
|
||||
enum class ActionType {
|
||||
Send,
|
||||
Schedule,
|
||||
};
|
||||
using Action = std::variant<Api::SendOptions, ActionType>;
|
||||
[[nodiscard]] Fn<void(Action, Details)> DefaultCallback(
|
||||
std::shared_ptr<ChatHelpers::Show> show,
|
||||
Type type,
|
||||
Fn<void(Api::SendOptions)> send);
|
||||
Fn<void()> DefaultWhenOnlineCallback(Fn<void(Api::SendOptions)> send);
|
||||
|
||||
FillMenuResult FillSendMenu(
|
||||
not_null<Ui::PopupMenu*> menu,
|
||||
Type type,
|
||||
Fn<void()> silent,
|
||||
Fn<void()> schedule,
|
||||
Fn<void()> whenOnline,
|
||||
const style::ComposeIcons *iconsOverride = nullptr);
|
||||
std::shared_ptr<ChatHelpers::Show> showForEffect,
|
||||
Details details,
|
||||
Fn<void(Action, Details)> action,
|
||||
const style::ComposeIcons *iconsOverride = nullptr,
|
||||
std::optional<QPoint> desiredPositionOverride = std::nullopt);
|
||||
|
||||
void SetupMenuAndShortcuts(
|
||||
not_null<Ui::RpWidget*> button,
|
||||
std::shared_ptr<ChatHelpers::Show> show,
|
||||
Fn<Type()> type,
|
||||
Fn<void()> silent,
|
||||
Fn<void()> schedule,
|
||||
Fn<void()> whenOnline);
|
||||
Fn<Details()> details,
|
||||
Fn<void(Action, Details)> action);
|
||||
|
||||
void SetupUnreadMentionsMenu(
|
||||
not_null<Ui::RpWidget*> button,
|
||||
|
|
|
@ -242,7 +242,6 @@ private:
|
|||
mtpRequestId *const saveEditMsgRequestId,
|
||||
std::optional<bool> spoilerMediaOverride);
|
||||
void chooseAttach(std::optional<bool> overrideSendImagesAsPhotos);
|
||||
[[nodiscard]] SendMenu::Type sendMenuType() const;
|
||||
[[nodiscard]] FullReplyTo replyTo() const;
|
||||
void doSetInnerFocus();
|
||||
void showAtPosition(
|
||||
|
@ -792,7 +791,7 @@ QPointer<Ui::RpWidget> ShortcutMessages::createPinnedToBottom(
|
|||
listShowPremiumToast(emoji);
|
||||
},
|
||||
.mode = HistoryView::ComposeControlsMode::Normal,
|
||||
.sendMenuType = SendMenu::Type::Disabled,
|
||||
.sendMenuDetails = [] { return SendMenu::Details(); },
|
||||
.regularWindow = _controller,
|
||||
.stickerOrEmojiChosen = _controller->stickerOrEmojiChosen(),
|
||||
.customPlaceholder = std::move(placeholder),
|
||||
|
@ -1346,7 +1345,7 @@ bool ShortcutMessages::confirmSendingFiles(
|
|||
_composeControls->getTextWithAppliedMarkdown(),
|
||||
_history->peer,
|
||||
Api::SendType::Normal,
|
||||
SendMenu::Type::Disabled);
|
||||
SendMenu::Details());
|
||||
|
||||
box->setConfirmedCallback(crl::guard(this, [=](
|
||||
Ui::PreparedList &&list,
|
||||
|
@ -1543,12 +1542,6 @@ void ShortcutMessages::sendInlineResult(
|
|||
return;
|
||||
}
|
||||
sendInlineResult(result, bot, {}, std::nullopt);
|
||||
//const auto callback = [=](Api::SendOptions options) {
|
||||
// sendInlineResult(result, bot, options);
|
||||
//};
|
||||
//Ui::show(
|
||||
// PrepareScheduleBox(this, sendMenuType(), callback),
|
||||
// Ui::LayerOption::KeepOther);
|
||||
}
|
||||
|
||||
void ShortcutMessages::sendInlineResult(
|
||||
|
|
|
@ -1141,7 +1141,7 @@ void Filler::addCreatePoll() {
|
|||
flag,
|
||||
flag,
|
||||
source,
|
||||
sendMenuType);
|
||||
{ sendMenuType });
|
||||
};
|
||||
_addAction(
|
||||
tr::lng_polls_create(tr::now),
|
||||
|
@ -1589,7 +1589,7 @@ void PeerMenuCreatePoll(
|
|||
PollData::Flags chosen,
|
||||
PollData::Flags disabled,
|
||||
Api::SendType sendType,
|
||||
SendMenu::Type sendMenuType) {
|
||||
SendMenu::Details sendMenuDetails) {
|
||||
if (peer->isChannel() && !peer->isMegagroup()) {
|
||||
chosen &= ~PollData::Flag::PublicVotes;
|
||||
disabled |= PollData::Flag::PublicVotes;
|
||||
|
@ -1599,7 +1599,7 @@ void PeerMenuCreatePoll(
|
|||
chosen,
|
||||
disabled,
|
||||
sendType,
|
||||
sendMenuType);
|
||||
sendMenuDetails);
|
||||
const auto weak = Ui::MakeWeak(box.data());
|
||||
const auto lock = box->lifetime().make_state<bool>(false);
|
||||
box->submitRequests(
|
||||
|
@ -2071,17 +2071,14 @@ QPointer<Ui::BoxContent> ShowForwardMessagesBox(
|
|||
|
||||
state->menu->addSeparator();
|
||||
}
|
||||
const auto type = sendMenuType();
|
||||
state->menu->setForcedVerticalOrigin(
|
||||
Ui::PopupMenu::VerticalOrigin::Bottom);
|
||||
const auto result = SendMenu::FillSendMenu(
|
||||
state->menu.get(),
|
||||
type,
|
||||
SendMenu::DefaultSilentCallback(submit),
|
||||
SendMenu::DefaultScheduleCallback(show, type, submit),
|
||||
SendMenu::DefaultWhenOnlineCallback(submit));
|
||||
const auto success = (result == SendMenu::FillMenuResult::Success);
|
||||
if (showForwardOptions || success) {
|
||||
state->menu->setForcedVerticalOrigin(
|
||||
Ui::PopupMenu::VerticalOrigin::Bottom);
|
||||
show,
|
||||
SendMenu::Details{ sendMenuType() },
|
||||
SendMenu::DefaultCallback(show, crl::guard(parent, submit)));
|
||||
if (showForwardOptions || !state->menu->empty()) {
|
||||
state->menu->popup(QCursor::pos());
|
||||
}
|
||||
};
|
||||
|
|
|
@ -91,7 +91,7 @@ void PeerMenuCreatePoll(
|
|||
PollData::Flags chosen = PollData::Flags(),
|
||||
PollData::Flags disabled = PollData::Flags(),
|
||||
Api::SendType sendType = Api::SendType::Normal,
|
||||
SendMenu::Type sendMenuType = SendMenu::Type::Scheduled);
|
||||
SendMenu::Details sendMenuDetails = SendMenu::Details());
|
||||
void PeerMenuDeleteTopicWithConfirmation(
|
||||
not_null<Window::SessionNavigation*> navigation,
|
||||
not_null<Data::ForumTopic*> topic);
|
||||
|
|
|
@ -122,7 +122,7 @@ public:
|
|||
rpl::producer<> pauseChanged() const override;
|
||||
|
||||
rpl::producer<bool> adjustShadowLeft() const override;
|
||||
SendMenu::Type sendMenuType() const override;
|
||||
SendMenu::Details sendMenuDetails() const override;
|
||||
|
||||
bool showMediaPreview(
|
||||
Data::FileOrigin origin,
|
||||
|
@ -272,12 +272,12 @@ rpl::producer<bool> MainWindowShow::adjustShadowLeft() const {
|
|||
});
|
||||
}
|
||||
|
||||
SendMenu::Type MainWindowShow::sendMenuType() const {
|
||||
SendMenu::Details MainWindowShow::sendMenuDetails() const {
|
||||
const auto window = _window.get();
|
||||
if (!window) {
|
||||
return SendMenu::Type::Disabled;
|
||||
return SendMenu::Details();
|
||||
}
|
||||
return window->content()->sendMenuType();
|
||||
return window->content()->sendMenuDetails();
|
||||
}
|
||||
|
||||
bool MainWindowShow::showMediaPreview(
|
||||
|
|
Loading…
Add table
Reference in a new issue