Added ability to set forward options from ShareBox.

This commit is contained in:
23rd 2022-02-03 00:58:21 +03:00 committed by John Preston
parent 02c9b61840
commit 641bb01ba2
7 changed files with 229 additions and 52 deletions

View file

@ -1116,7 +1116,8 @@ void ShareInviteLinkBox(not_null<PeerData*> peer, const QString &link) {
auto submitCallback = [=](
std::vector<not_null<PeerData*>> &&result,
TextWithTags &&comment,
Api::SendOptions options) {
Api::SendOptions options,
Data::ForwardOptions) {
if (*sending || result.empty()) {
return;
}

View file

@ -15,11 +15,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "storage/storage_account.h"
#include "ui/boxes/confirm_box.h"
#include "apiwrap.h"
#include "ui/chat/forward_options_box.h"
#include "ui/toast/toast.h"
#include "ui/widgets/checkbox.h"
#include "ui/widgets/multi_select.h"
#include "ui/widgets/buttons.h"
#include "ui/widgets/scroll_area.h"
#include "ui/widgets/input_fields.h"
#include "ui/widgets/menu/menu_action.h"
#include "ui/widgets/popup_menu.h"
#include "ui/wrap/slide_wrap.h"
#include "ui/text/text_options.h"
#include "chat_helpers/message_field.h"
@ -40,6 +44,44 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "styles/style_layers.h"
#include "styles/style_boxes.h"
#include "styles/style_chat.h"
#include "styles/style_menu_icons.h"
#include "styles/style_media_player.h"
namespace {
class ForwardOptionItem final : public Ui::Menu::Action {
public:
using Ui::Menu::Action::Action;
void init(bool checked) {
enableMouseSelecting();
AbstractButton::setDisabled(true);
_checkView = std::make_unique<Ui::CheckView>(st::defaultCheck, false);
_checkView->checkedChanges(
) | rpl::start_with_next([=](bool checked) {
setIcon(checked ? &st::mediaPlayerMenuCheck : nullptr);
}, lifetime());
_checkView->setChecked(checked, anim::type::normal);
AbstractButton::clicks(
) | rpl::start_with_next([=] {
_checkView->setChecked(
!_checkView->checked(),
anim::type::normal);
}, lifetime());
}
not_null<Ui::CheckView*> checkView() const {
return _checkView.get();
}
private:
std::unique_ptr<Ui::CheckView> _checkView;
};
} // namespace
class ShareBox::Inner final : public Ui::RpWidget {
public:
@ -442,17 +484,68 @@ SendMenu::Type ShareBox::sendMenuType() const {
: SendMenu::Type::Scheduled;
}
void ShareBox::showMenu(not_null<Ui::RpWidget*> parent) {
if (_menu) {
_menu = nullptr;
return;
}
_menu.emplace(parent, st::popupMenuWithIcons);
if (_descriptor.forwardOptions.show) {
auto createView = [&](rpl::producer<QString> &&text, bool checked) {
auto item = base::make_unique_q<ForwardOptionItem>(
_menu->menu(),
st::popupMenuWithIcons.menu,
new QAction(QString(), _menu->menu()),
nullptr,
nullptr);
std::move(
text
) | rpl::start_with_next([action = item->action()](QString text) {
action->setText(text);
}, item->lifetime());
item->init(checked);
const auto view = item->checkView();
_menu->addAction(std::move(item));
return view;
};
Ui::FillForwardOptions(
std::move(createView),
_descriptor.forwardOptions.messagesCount,
_forwardOptions,
[=](Ui::ForwardOptions value) { _forwardOptions = value; },
_menu->lifetime());
_menu->addSeparator();
}
const auto result = SendMenu::FillSendMenu(
_menu.get(),
sendMenuType(),
[=] { submitSilent(); },
[=] { submitScheduled(); });
const auto success = (result == SendMenu::FillMenuResult::Success);
if (_descriptor.forwardOptions.show || success) {
_menu->setForcedOrigin(Ui::PanelAnimation::Origin::BottomRight);
_menu->popup(QCursor::pos());
}
}
void ShareBox::createButtons() {
clearButtons();
if (_hasSelected) {
const auto send = addButton(tr::lng_share_confirm(), [=] {
submit({});
});
SendMenu::SetupMenuAndShortcuts(
send,
[=] { return sendMenuType(); },
[=] { submitSilent(); },
[=] { submitScheduled(); });
_forwardOptions.hasCaptions = _descriptor.forwardOptions.hasCaptions;
send->setAcceptBoth();
send->clicks(
) | rpl::start_with_next([=](Qt::MouseButton button) {
if (button == Qt::RightButton) {
showMenu(send);
}
}, send->lifetime());
} else if (_descriptor.copyCallback) {
addButton(_copyLinkText.value(), [=] { copyLink(); });
}
@ -488,10 +581,17 @@ void ShareBox::innerSelectedChanged(PeerData *peer, bool checked) {
void ShareBox::submit(Api::SendOptions options) {
if (const auto onstack = _descriptor.submitCallback) {
const auto forwardOptions = (_forwardOptions.hasCaptions
&& _forwardOptions.dropCaptions)
? Data::ForwardOptions::NoNamesAndCaptions
: _forwardOptions.dropNames
? Data::ForwardOptions::NoSenderNames
: Data::ForwardOptions::PreserveInfo;
onstack(
_inner->selected(),
_comment->entity()->getTextWithAppliedMarkdown(),
options);
options,
forwardOptions);
}
}

View file

@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "boxes/abstract_box.h"
#include "base/observer.h"
#include "base/timer.h"
#include "ui/chat/forward_options_box.h"
#include "ui/effects/animations.h"
#include "ui/effects/round_checkbox.h"
#include "mtproto/sender.h"
@ -41,12 +42,17 @@ class Row;
class IndexedList;
} // namespace Dialogs
namespace Data {
enum class ForwardOptions;
} // namespace Data
namespace Ui {
class MultiSelect;
class InputField;
struct ScrollToRequest;
template <typename Widget>
class SlideWrap;
class PopupMenu;
} // namespace Ui
QString AppendShareGameScoreUrl(
@ -63,7 +69,8 @@ public:
using SubmitCallback = Fn<void(
std::vector<not_null<PeerData*>>&&,
TextWithTags&&,
Api::SendOptions)>;
Api::SendOptions,
Data::ForwardOptions option)>;
using FilterCallback = Fn<bool(PeerData*)>;
struct Descriptor {
@ -79,6 +86,11 @@ public:
const style::MultiSelect *stMultiSelect = nullptr;
const style::InputField *stComment = nullptr;
const style::PeerList *st = nullptr;
struct {
int messagesCount = 0;
bool show = false;
bool hasCaptions = false;
} forwardOptions;
};
ShareBox(QWidget*, Descriptor &&descriptor);
@ -119,6 +131,8 @@ private:
mtpRequestId requestId);
void peopleFail(const MTP::Error &error, mtpRequestId requestId);
void showMenu(not_null<Ui::RpWidget*> parent);
Descriptor _descriptor;
MTP::Sender _api;
@ -126,6 +140,9 @@ private:
object_ptr<Ui::SlideWrap<Ui::InputField>> _comment;
object_ptr<Ui::RpWidget> _bottomWidget;
base::unique_qptr<Ui::PopupMenu> _menu;
Ui::ForwardOptions _forwardOptions;
class Inner;
QPointer<Inner> _inner;

View file

@ -129,7 +129,8 @@ object_ptr<ShareBox> ShareInviteLinkBox(
auto submitCallback = [=](
std::vector<not_null<PeerData*>> &&result,
TextWithTags &&comment,
Api::SendOptions options) {
Api::SendOptions options,
Data::ForwardOptions) {
if (*sending || result.empty()) {
return;
}

View file

@ -209,6 +209,18 @@ void FastShareMessage(not_null<HistoryItem*> item) {
&& (item->media()->game() != nullptr);
const auto canCopyLink = item->hasDirectLink() || isGame;
const auto items = owner->idsToItems(data->msgIds);
const auto hasCaptions = ranges::any_of(items, [](auto item) {
return item->media()
&& !item->originalText().text.isEmpty()
&& item->media()->allowsEditCaption();
});
const auto hasOnlyForcedForwardedInfo = hasCaptions
? false
: ranges::all_of(items, [](auto item) {
return item->media() && item->media()->forceForwardedInfo();
});
auto copyCallback = [=]() {
if (const auto item = owner->message(data->msgIds[0])) {
if (item->hasDirectLink()) {
@ -235,7 +247,8 @@ void FastShareMessage(not_null<HistoryItem*> item) {
auto submitCallback = [=](
std::vector<not_null<PeerData*>> &&result,
TextWithTags &&comment,
Api::SendOptions options) {
Api::SendOptions options,
Data::ForwardOptions forwardOptions) {
if (!data->requests.empty()) {
return; // Share clicked already.
}
@ -274,6 +287,12 @@ void FastShareMessage(not_null<HistoryItem*> item) {
| MTPmessages_ForwardMessages::Flag::f_with_my_score
| (options.scheduled
? MTPmessages_ForwardMessages::Flag::f_schedule_date
: MTPmessages_ForwardMessages::Flag(0))
| ((forwardOptions != Data::ForwardOptions::PreserveInfo)
? MTPmessages_ForwardMessages::Flag::f_drop_author
: MTPmessages_ForwardMessages::Flag(0))
| ((forwardOptions == Data::ForwardOptions::NoNamesAndCaptions)
? MTPmessages_ForwardMessages::Flag::f_drop_media_captions
: MTPmessages_ForwardMessages::Flag(0));
auto msgIds = QVector<MTPint>();
msgIds.reserve(data->msgIds.size());
@ -346,7 +365,13 @@ void FastShareMessage(not_null<HistoryItem*> item) {
.copyCallback = std::move(copyLinkCallback),
.submitCallback = std::move(submitCallback),
.filterCallback = std::move(filterCallback),
.navigation = App::wnd()->sessionController() }));
.navigation = App::wnd()->sessionController(),
.forwardOptions = {
.messagesCount = int(data->msgIds.size()),
.show = !hasOnlyForcedForwardedInfo,
.hasCaptions = hasCaptions,
},
}));
}
void RequestDependentMessageData(

View file

@ -15,6 +15,56 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace Ui {
void FillForwardOptions(
Fn<not_null<AbstractCheckView*>(
rpl::producer<QString> &&,
bool)> createView,
int count,
ForwardOptions options,
Fn<void(ForwardOptions)> optionsChanged,
rpl::lifetime &lifetime) {
Expects(optionsChanged != nullptr);
const auto names = createView(
(count == 1
? tr::lng_forward_show_sender
: tr::lng_forward_show_senders)(),
!options.dropNames);
const auto captions = options.hasCaptions
? createView(
(count == 1
? tr::lng_forward_show_caption
: tr::lng_forward_show_captions)(),
!options.dropCaptions).get()
: nullptr;
const auto notify = [=] {
optionsChanged({
.dropNames = !names->checked(),
.hasCaptions = options.hasCaptions,
.dropCaptions = (captions && !captions->checked()),
});
};
names->checkedChanges(
) | rpl::start_with_next([=](bool showNames) {
if (showNames && captions && !captions->checked()) {
captions->setChecked(true, anim::type::normal);
} else {
notify();
}
}, lifetime);
if (captions) {
captions->checkedChanges(
) | rpl::start_with_next([=](bool showCaptions) {
if (!showCaptions && names->checked()) {
names->setChecked(false, anim::type::normal);
} else {
notify();
}
}, lifetime);
}
}
void ForwardOptionsBox(
not_null<GenericBox*> box,
int count,
@ -45,51 +95,23 @@ void ForwardOptionsBox(
st::boxRowPadding.left(),
st::boxRowPadding.right(),
st::boxRowPadding.bottom());
const auto names = box->addRow(
object_ptr<Ui::Checkbox>(
box.get(),
(count == 1
? tr::lng_forward_show_sender
: tr::lng_forward_show_senders)(),
!options.dropNames,
st::defaultBoxCheckbox),
checkboxPadding);
const auto captions = options.hasCaptions
? box->addRow(
auto createView = [&](rpl::producer<QString> &&text, bool checked) {
return box->addRow(
object_ptr<Ui::Checkbox>(
box.get(),
(count == 1
? tr::lng_forward_show_caption
: tr::lng_forward_show_captions)(),
!options.dropCaptions,
std::move(text),
checked,
st::defaultBoxCheckbox),
checkboxPadding)
: nullptr;
const auto notify = [=] {
optionsChanged({
.dropNames = !names->checked(),
.hasCaptions = options.hasCaptions,
.dropCaptions = (captions && !captions->checked()),
});
checkboxPadding)->checkView();
};
names->checkedChanges(
) | rpl::start_with_next([=](bool showNames) {
if (showNames && captions && !captions->checked()) {
captions->setChecked(true);
} else {
notify();
}
}, names->lifetime());
if (captions) {
captions->checkedChanges(
) | rpl::start_with_next([=](bool showCaptions) {
if (!showCaptions && names->checked()) {
names->setChecked(false);
} else {
notify();
}
}, captions->lifetime());
}
FillForwardOptions(
std::move(createView),
count,
options,
std::move(optionsChanged),
box->lifetime());
box->addRow(
object_ptr<Ui::LinkButton>(
box.get(),

View file

@ -11,12 +11,23 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace Ui {
class AbstractCheckView;
struct ForwardOptions {
bool dropNames = false;
bool hasCaptions = false;
bool dropCaptions = false;
};
void FillForwardOptions(
Fn<not_null<AbstractCheckView*>(
rpl::producer<QString> &&,
bool)> createView,
int count,
ForwardOptions options,
Fn<void(ForwardOptions)> optionsChanged,
rpl::lifetime &lifetime);
void ForwardOptionsBox(
not_null<GenericBox*> box,
int count,