mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Added ability to insert custom emoji to polls.
This commit is contained in:
parent
e6c22ec1ca
commit
c803603de4
3 changed files with 235 additions and 40 deletions
|
@ -691,6 +691,10 @@ createPollOptionField: InputField(createPollField) {
|
||||||
placeholderMargins: margins(2px, 0px, 2px, 0px);
|
placeholderMargins: margins(2px, 0px, 2px, 0px);
|
||||||
heightMax: 68px;
|
heightMax: 68px;
|
||||||
}
|
}
|
||||||
|
createPollOptionFieldPremium: InputField(createPollOptionField) {
|
||||||
|
textMargins: margins(22px, 11px, 68px, 11px);
|
||||||
|
}
|
||||||
|
createPollOptionFieldPremiumEmojiPosition: point(15px, -1px);
|
||||||
createPollSolutionField: InputField(createPollField) {
|
createPollSolutionField: InputField(createPollField) {
|
||||||
textMargins: margins(0px, 4px, 0px, 4px);
|
textMargins: margins(0px, 4px, 0px, 4px);
|
||||||
border: 1px;
|
border: 1px;
|
||||||
|
@ -704,7 +708,7 @@ createPollOptionRemove: CrossButton {
|
||||||
cross: CrossAnimation {
|
cross: CrossAnimation {
|
||||||
size: 22px;
|
size: 22px;
|
||||||
skip: 6px;
|
skip: 6px;
|
||||||
stroke: 1.;
|
stroke: 1.5;
|
||||||
minScale: 0.3;
|
minScale: 0.3;
|
||||||
}
|
}
|
||||||
crossFg: boxTitleCloseFg;
|
crossFg: boxTitleCloseFg;
|
||||||
|
@ -718,6 +722,7 @@ createPollOptionRemove: CrossButton {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
createPollOptionRemovePosition: point(11px, 9px);
|
createPollOptionRemovePosition: point(11px, 9px);
|
||||||
|
createPollOptionEmojiPositionSkip: 4px;
|
||||||
createPollWarning: FlatLabel(defaultFlatLabel) {
|
createPollWarning: FlatLabel(defaultFlatLabel) {
|
||||||
textFg: windowSubTextFg;
|
textFg: windowSubTextFg;
|
||||||
palette: TextPalette(defaultTextPalette) {
|
palette: TextPalette(defaultTextPalette) {
|
||||||
|
|
|
@ -7,33 +7,41 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#include "boxes/create_poll_box.h"
|
#include "boxes/create_poll_box.h"
|
||||||
|
|
||||||
#include "lang/lang_keys.h"
|
#include "base/call_delayed.h"
|
||||||
#include "data/data_poll.h"
|
#include "base/event_filter.h"
|
||||||
#include "ui/toast/toast.h"
|
#include "base/random.h"
|
||||||
#include "ui/wrap/vertical_layout.h"
|
#include "base/unique_qptr.h"
|
||||||
#include "ui/wrap/slide_wrap.h"
|
|
||||||
#include "ui/wrap/fade_wrap.h"
|
|
||||||
#include "ui/widgets/fields/input_field.h"
|
|
||||||
#include "ui/widgets/shadow.h"
|
|
||||||
#include "ui/widgets/labels.h"
|
|
||||||
#include "ui/widgets/buttons.h"
|
|
||||||
#include "ui/widgets/checkbox.h"
|
|
||||||
#include "ui/text/text_utilities.h"
|
|
||||||
#include "ui/vertical_list.h"
|
|
||||||
#include "main/main_session.h"
|
|
||||||
#include "core/application.h"
|
|
||||||
#include "core/core_settings.h"
|
|
||||||
#include "chat_helpers/emoji_suggestions_widget.h"
|
#include "chat_helpers/emoji_suggestions_widget.h"
|
||||||
#include "chat_helpers/message_field.h"
|
#include "chat_helpers/message_field.h"
|
||||||
#include "menu/menu_send.h"
|
#include "chat_helpers/tabbed_panel.h"
|
||||||
|
#include "chat_helpers/tabbed_selector.h"
|
||||||
|
#include "core/application.h"
|
||||||
|
#include "core/core_settings.h"
|
||||||
|
#include "data/data_poll.h"
|
||||||
|
#include "data/data_user.h"
|
||||||
|
#include "data/stickers/data_custom_emoji.h"
|
||||||
#include "history/view/history_view_schedule_box.h"
|
#include "history/view/history_view_schedule_box.h"
|
||||||
#include "base/unique_qptr.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "base/event_filter.h"
|
#include "main/main_session.h"
|
||||||
#include "base/call_delayed.h"
|
#include "menu/menu_send.h"
|
||||||
#include "base/random.h"
|
#include "ui/controls/emoji_button.h"
|
||||||
|
#include "ui/rect.h"
|
||||||
|
#include "ui/text/text_utilities.h"
|
||||||
|
#include "ui/toast/toast.h"
|
||||||
|
#include "ui/vertical_list.h"
|
||||||
|
#include "ui/widgets/buttons.h"
|
||||||
|
#include "ui/widgets/checkbox.h"
|
||||||
|
#include "ui/widgets/fields/input_field.h"
|
||||||
|
#include "ui/widgets/labels.h"
|
||||||
|
#include "ui/widgets/shadow.h"
|
||||||
|
#include "ui/wrap/fade_wrap.h"
|
||||||
|
#include "ui/wrap/slide_wrap.h"
|
||||||
|
#include "ui/wrap/vertical_layout.h"
|
||||||
#include "window/window_session_controller.h"
|
#include "window/window_session_controller.h"
|
||||||
#include "styles/style_layers.h"
|
|
||||||
#include "styles/style_boxes.h"
|
#include "styles/style_boxes.h"
|
||||||
|
#include "styles/style_chat_helpers.h" // defaultComposeFiles.
|
||||||
|
#include "styles/style_layers.h"
|
||||||
|
#include "styles/style_settings.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
@ -46,12 +54,107 @@ constexpr auto kSolutionLimit = 200;
|
||||||
constexpr auto kWarnSolutionLimit = 60;
|
constexpr auto kWarnSolutionLimit = 60;
|
||||||
constexpr auto kErrorLimit = 99;
|
constexpr auto kErrorLimit = 99;
|
||||||
|
|
||||||
|
[[nodiscard]] not_null<Ui::EmojiButton*> AddEmojiToggleToField(
|
||||||
|
not_null<Ui::InputField*> field,
|
||||||
|
not_null<Ui::BoxContent*> box,
|
||||||
|
not_null<Window::SessionController*> controller,
|
||||||
|
not_null<ChatHelpers::TabbedPanel*> emojiPanel,
|
||||||
|
QPoint shift) {
|
||||||
|
const auto emojiToggle = Ui::CreateChild<Ui::EmojiButton>(
|
||||||
|
field->parentWidget(),
|
||||||
|
st::defaultComposeFiles.emoji);
|
||||||
|
const auto fade = Ui::CreateChild<Ui::FadeAnimation>(
|
||||||
|
emojiToggle,
|
||||||
|
emojiToggle,
|
||||||
|
0.5);
|
||||||
|
{
|
||||||
|
const auto fadeTarget = Ui::CreateChild<Ui::RpWidget>(emojiToggle);
|
||||||
|
fadeTarget->resize(emojiToggle->size());
|
||||||
|
fadeTarget->paintRequest(
|
||||||
|
) | rpl::start_with_next([=](const QRect &rect) {
|
||||||
|
auto p = QPainter(fadeTarget);
|
||||||
|
if (fade->animating()) {
|
||||||
|
p.fillRect(fadeTarget->rect(), st::boxBg);
|
||||||
|
}
|
||||||
|
fade->paint(p);
|
||||||
|
}, fadeTarget->lifetime());
|
||||||
|
rpl::single(false) | rpl::then(
|
||||||
|
field->focusedChanges()
|
||||||
|
) | rpl::start_with_next([=](bool shown) {
|
||||||
|
if (shown) {
|
||||||
|
fade->fadeIn(st::universalDuration);
|
||||||
|
} else {
|
||||||
|
fade->fadeOut(st::universalDuration);
|
||||||
|
}
|
||||||
|
}, emojiToggle->lifetime());
|
||||||
|
fade->fadeOut(1);
|
||||||
|
fade->finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const auto outer = box->getDelegate()->outerContainer();
|
||||||
|
const auto allow = [](not_null<DocumentData*>) { return true; };
|
||||||
|
InitMessageFieldHandlers(
|
||||||
|
controller,
|
||||||
|
field,
|
||||||
|
Window::GifPauseReason::Layer,
|
||||||
|
allow);
|
||||||
|
Ui::Emoji::SuggestionsController::Init(
|
||||||
|
outer,
|
||||||
|
field,
|
||||||
|
&controller->session(),
|
||||||
|
Ui::Emoji::SuggestionsController::Options{
|
||||||
|
.suggestCustomEmoji = true,
|
||||||
|
.allowCustomWithoutPremium = allow,
|
||||||
|
});
|
||||||
|
const auto updateEmojiPanelGeometry = [=] {
|
||||||
|
const auto parent = emojiPanel->parentWidget();
|
||||||
|
const auto global = emojiToggle->mapToGlobal({ 0, 0 });
|
||||||
|
const auto local = parent->mapFromGlobal(global);
|
||||||
|
const auto right = local.x() + emojiToggle->width() * 3;
|
||||||
|
const auto isDropDown = local.y() < parent->height() / 2;
|
||||||
|
emojiPanel->setDropDown(isDropDown);
|
||||||
|
if (isDropDown) {
|
||||||
|
emojiPanel->moveTopRight(
|
||||||
|
local.y() + emojiToggle->height(),
|
||||||
|
right);
|
||||||
|
} else {
|
||||||
|
emojiPanel->moveBottomRight(local.y(), right);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
rpl::combine(
|
||||||
|
box->sizeValue(),
|
||||||
|
field->geometryValue()
|
||||||
|
) | rpl::start_with_next([=](QSize outer, QRect inner) {
|
||||||
|
emojiToggle->moveToLeft(
|
||||||
|
rect::right(inner) + shift.x(),
|
||||||
|
inner.y() + shift.y());
|
||||||
|
emojiToggle->update();
|
||||||
|
}, emojiToggle->lifetime());
|
||||||
|
|
||||||
|
emojiToggle->installEventFilter(emojiPanel);
|
||||||
|
emojiToggle->addClickHandler([=] {
|
||||||
|
updateEmojiPanelGeometry();
|
||||||
|
emojiPanel->toggleAnimated();
|
||||||
|
});
|
||||||
|
const auto filterCallback = [=](not_null<QEvent*> event) {
|
||||||
|
if (event->type() == QEvent::Enter) {
|
||||||
|
updateEmojiPanelGeometry();
|
||||||
|
}
|
||||||
|
return base::EventFilterResult::Continue;
|
||||||
|
};
|
||||||
|
base::install_event_filter(emojiToggle, filterCallback);
|
||||||
|
|
||||||
|
return emojiToggle;
|
||||||
|
}
|
||||||
|
|
||||||
class Options {
|
class Options {
|
||||||
public:
|
public:
|
||||||
Options(
|
Options(
|
||||||
not_null<QWidget*> outer,
|
not_null<Ui::BoxContent*> box,
|
||||||
not_null<Ui::VerticalLayout*> container,
|
not_null<Ui::VerticalLayout*> container,
|
||||||
not_null<Main::Session*> session,
|
not_null<Window::SessionController*> controller,
|
||||||
|
ChatHelpers::TabbedPanel *emojiPanel,
|
||||||
bool chooseCorrectEnabled);
|
bool chooseCorrectEnabled);
|
||||||
|
|
||||||
[[nodiscard]] bool hasOptions() const;
|
[[nodiscard]] bool hasOptions() const;
|
||||||
|
@ -140,9 +243,10 @@ private:
|
||||||
[[nodiscard]] auto createChooseCorrectGroup()
|
[[nodiscard]] auto createChooseCorrectGroup()
|
||||||
-> std::shared_ptr<Ui::RadiobuttonGroup>;
|
-> std::shared_ptr<Ui::RadiobuttonGroup>;
|
||||||
|
|
||||||
not_null<QWidget*> _outer;
|
not_null<Ui::BoxContent*> _box;
|
||||||
not_null<Ui::VerticalLayout*> _container;
|
not_null<Ui::VerticalLayout*> _container;
|
||||||
const not_null<Main::Session*> _session;
|
const not_null<Window::SessionController*> _controller;
|
||||||
|
ChatHelpers::TabbedPanel * const _emojiPanel;
|
||||||
std::shared_ptr<Ui::RadiobuttonGroup> _chooseCorrectGroup;
|
std::shared_ptr<Ui::RadiobuttonGroup> _chooseCorrectGroup;
|
||||||
int _position = 0;
|
int _position = 0;
|
||||||
std::vector<std::unique_ptr<Option>> _list;
|
std::vector<std::unique_ptr<Option>> _list;
|
||||||
|
@ -154,6 +258,7 @@ private:
|
||||||
rpl::event_stream<not_null<QWidget*>> _scrollToWidget;
|
rpl::event_stream<not_null<QWidget*>> _scrollToWidget;
|
||||||
rpl::event_stream<> _backspaceInFront;
|
rpl::event_stream<> _backspaceInFront;
|
||||||
rpl::event_stream<> _tabbed;
|
rpl::event_stream<> _tabbed;
|
||||||
|
rpl::lifetime _emojiPanelLifetime;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -193,8 +298,9 @@ not_null<Ui::FlatLabel*> CreateWarningLabel(
|
||||||
if (value >= 0) {
|
if (value >= 0) {
|
||||||
result->setText(QString::number(value));
|
result->setText(QString::number(value));
|
||||||
} else {
|
} else {
|
||||||
|
constexpr auto kMinus = QChar(0x2212);
|
||||||
result->setMarkedText(Ui::Text::Colorized(
|
result->setMarkedText(Ui::Text::Colorized(
|
||||||
QString::number(value)));
|
kMinus + QString::number(std::abs(value))));
|
||||||
}
|
}
|
||||||
result->setVisible(shown);
|
result->setVisible(shown);
|
||||||
}));
|
}));
|
||||||
|
@ -223,7 +329,9 @@ Options::Option::Option(
|
||||||
, _field(
|
, _field(
|
||||||
Ui::CreateChild<Ui::InputField>(
|
Ui::CreateChild<Ui::InputField>(
|
||||||
_content.get(),
|
_content.get(),
|
||||||
st::createPollOptionField,
|
session->user()->isPremium()
|
||||||
|
? st::createPollOptionFieldPremium
|
||||||
|
: st::createPollOptionField,
|
||||||
Ui::InputField::Mode::NoNewlines,
|
Ui::InputField::Mode::NoNewlines,
|
||||||
tr::lng_polls_create_option_add())) {
|
tr::lng_polls_create_option_add())) {
|
||||||
InitField(outer, _field, session);
|
InitField(outer, _field, session);
|
||||||
|
@ -299,7 +407,7 @@ void Options::Option::createRemove() {
|
||||||
const auto remove = Ui::CreateChild<Ui::CrossButton>(
|
const auto remove = Ui::CreateChild<Ui::CrossButton>(
|
||||||
field.get(),
|
field.get(),
|
||||||
st::createPollOptionRemove);
|
st::createPollOptionRemove);
|
||||||
remove->hide(anim::type::instant);
|
remove->show(anim::type::instant);
|
||||||
|
|
||||||
const auto toggle = lifetime.make_state<rpl::variable<bool>>(false);
|
const auto toggle = lifetime.make_state<rpl::variable<bool>>(false);
|
||||||
_removeAlways = lifetime.make_state<rpl::variable<bool>>(false);
|
_removeAlways = lifetime.make_state<rpl::variable<bool>>(false);
|
||||||
|
@ -309,6 +417,7 @@ void Options::Option::createRemove() {
|
||||||
// Don't capture 'this'! Because Option is a value type.
|
// Don't capture 'this'! Because Option is a value type.
|
||||||
*toggle = !field->getLastText().isEmpty();
|
*toggle = !field->getLastText().isEmpty();
|
||||||
}, field->lifetime());
|
}, field->lifetime());
|
||||||
|
#if 0
|
||||||
rpl::combine(
|
rpl::combine(
|
||||||
toggle->value(),
|
toggle->value(),
|
||||||
_removeAlways->value(),
|
_removeAlways->value(),
|
||||||
|
@ -316,6 +425,7 @@ void Options::Option::createRemove() {
|
||||||
) | rpl::start_with_next([=](bool shown) {
|
) | rpl::start_with_next([=](bool shown) {
|
||||||
remove->toggle(shown, anim::type::normal);
|
remove->toggle(shown, anim::type::normal);
|
||||||
}, remove->lifetime());
|
}, remove->lifetime());
|
||||||
|
#endif
|
||||||
|
|
||||||
field->widthValue(
|
field->widthValue(
|
||||||
) | rpl::start_with_next([=](int width) {
|
) | rpl::start_with_next([=](int width) {
|
||||||
|
@ -475,13 +585,15 @@ rpl::producer<Qt::MouseButton> Options::Option::removeClicks() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
Options::Options(
|
Options::Options(
|
||||||
not_null<QWidget*> outer,
|
not_null<Ui::BoxContent*> box,
|
||||||
not_null<Ui::VerticalLayout*> container,
|
not_null<Ui::VerticalLayout*> container,
|
||||||
not_null<Main::Session*> session,
|
not_null<Window::SessionController*> controller,
|
||||||
|
ChatHelpers::TabbedPanel *emojiPanel,
|
||||||
bool chooseCorrectEnabled)
|
bool chooseCorrectEnabled)
|
||||||
: _outer(outer)
|
: _box(box)
|
||||||
, _container(container)
|
, _container(container)
|
||||||
, _session(session)
|
, _controller(controller)
|
||||||
|
, _emojiPanel(emojiPanel)
|
||||||
, _chooseCorrectGroup(chooseCorrectEnabled
|
, _chooseCorrectGroup(chooseCorrectEnabled
|
||||||
? createChooseCorrectGroup()
|
? createChooseCorrectGroup()
|
||||||
: nullptr)
|
: nullptr)
|
||||||
|
@ -651,12 +763,40 @@ void Options::addEmptyOption() {
|
||||||
(*(_list.end() - 2))->toggleRemoveAlways(true);
|
(*(_list.end() - 2))->toggleRemoveAlways(true);
|
||||||
}
|
}
|
||||||
_list.push_back(std::make_unique<Option>(
|
_list.push_back(std::make_unique<Option>(
|
||||||
_outer,
|
_box,
|
||||||
_container,
|
_container,
|
||||||
_session,
|
&_controller->session(),
|
||||||
_position + _list.size() + _destroyed.size(),
|
_position + _list.size() + _destroyed.size(),
|
||||||
_chooseCorrectGroup));
|
_chooseCorrectGroup));
|
||||||
const auto field = _list.back()->field();
|
const auto field = _list.back()->field();
|
||||||
|
if (const auto emojiPanel = _emojiPanel) {
|
||||||
|
const auto emojiToggle = AddEmojiToggleToField(
|
||||||
|
field,
|
||||||
|
_box,
|
||||||
|
_controller,
|
||||||
|
emojiPanel,
|
||||||
|
QPoint(
|
||||||
|
-st::createPollOptionFieldPremium.textMargins.right(),
|
||||||
|
st::createPollOptionEmojiPositionSkip));
|
||||||
|
emojiToggle->shownValue() | rpl::start_with_next([=](bool shown) {
|
||||||
|
if (!shown) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_emojiPanelLifetime.destroy();
|
||||||
|
emojiPanel->selector()->emojiChosen(
|
||||||
|
) | rpl::start_with_next([=](ChatHelpers::EmojiChosen data) {
|
||||||
|
if (field->hasFocus()) {
|
||||||
|
Ui::InsertEmojiAtCursor(field->textCursor(), data.emoji);
|
||||||
|
}
|
||||||
|
}, _emojiPanelLifetime);
|
||||||
|
emojiPanel->selector()->customEmojiChosen(
|
||||||
|
) | rpl::start_with_next([=](ChatHelpers::FileChosen data) {
|
||||||
|
if (field->hasFocus()) {
|
||||||
|
Data::InsertCustomEmoji(field, data.document);
|
||||||
|
}
|
||||||
|
}, _emojiPanelLifetime);
|
||||||
|
}, emojiToggle->lifetime());
|
||||||
|
}
|
||||||
field->submits(
|
field->submits(
|
||||||
) | rpl::start_with_next([=] {
|
) | rpl::start_with_next([=] {
|
||||||
const auto index = findField(field);
|
const auto index = findField(field);
|
||||||
|
@ -703,7 +843,7 @@ void Options::addEmptyOption() {
|
||||||
});
|
});
|
||||||
|
|
||||||
_list.back()->removeClicks(
|
_list.back()->removeClicks(
|
||||||
) | rpl::take(1) | rpl::start_with_next([=] {
|
) | rpl::start_with_next([=] {
|
||||||
Ui::PostponeCall(crl::guard(field, [=] {
|
Ui::PostponeCall(crl::guard(field, [=] {
|
||||||
Expects(!_list.empty());
|
Expects(!_list.empty());
|
||||||
|
|
||||||
|
@ -795,19 +935,63 @@ not_null<Ui::InputField*> CreatePollBox::setupQuestion(
|
||||||
using namespace Settings;
|
using namespace Settings;
|
||||||
|
|
||||||
const auto session = &_controller->session();
|
const auto session = &_controller->session();
|
||||||
|
const auto isPremium = session->user()->isPremium();
|
||||||
Ui::AddSubsectionTitle(container, tr::lng_polls_create_question());
|
Ui::AddSubsectionTitle(container, tr::lng_polls_create_question());
|
||||||
|
|
||||||
const auto question = container->add(
|
const auto question = container->add(
|
||||||
object_ptr<Ui::InputField>(
|
object_ptr<Ui::InputField>(
|
||||||
container,
|
container,
|
||||||
st::createPollField,
|
st::createPollField,
|
||||||
Ui::InputField::Mode::MultiLine,
|
Ui::InputField::Mode::MultiLine,
|
||||||
tr::lng_polls_create_question_placeholder()),
|
tr::lng_polls_create_question_placeholder()),
|
||||||
st::createPollFieldPadding);
|
st::createPollFieldPadding
|
||||||
|
+ (isPremium
|
||||||
|
? QMargins(0, 0, st::defaultComposeFiles.emoji.inner.width, 0)
|
||||||
|
: QMargins()));
|
||||||
InitField(getDelegate()->outerContainer(), question, session);
|
InitField(getDelegate()->outerContainer(), question, session);
|
||||||
question->setMaxLength(kQuestionLimit + kErrorLimit);
|
question->setMaxLength(kQuestionLimit + kErrorLimit);
|
||||||
question->setSubmitSettings(Ui::InputField::SubmitSettings::Both);
|
question->setSubmitSettings(Ui::InputField::SubmitSettings::Both);
|
||||||
question->customTab(true);
|
question->customTab(true);
|
||||||
|
|
||||||
|
if (isPremium) {
|
||||||
|
using Selector = ChatHelpers::TabbedSelector;
|
||||||
|
const auto outer = getDelegate()->outerContainer();
|
||||||
|
_emojiPanel = base::make_unique_q<ChatHelpers::TabbedPanel>(
|
||||||
|
outer,
|
||||||
|
_controller,
|
||||||
|
object_ptr<Selector>(
|
||||||
|
nullptr,
|
||||||
|
_controller->uiShow(),
|
||||||
|
Window::GifPauseReason::Layer,
|
||||||
|
Selector::Mode::EmojiOnly));
|
||||||
|
const auto emojiPanel = _emojiPanel.get();
|
||||||
|
emojiPanel->setDesiredHeightValues(
|
||||||
|
1.,
|
||||||
|
st::emojiPanMinHeight / 2,
|
||||||
|
st::emojiPanMinHeight);
|
||||||
|
emojiPanel->hide();
|
||||||
|
emojiPanel->selector()->setCurrentPeer(session->user());
|
||||||
|
|
||||||
|
const auto emojiToggle = AddEmojiToggleToField(
|
||||||
|
question,
|
||||||
|
this,
|
||||||
|
_controller,
|
||||||
|
emojiPanel,
|
||||||
|
st::createPollOptionFieldPremiumEmojiPosition);
|
||||||
|
emojiPanel->selector()->emojiChosen(
|
||||||
|
) | rpl::start_with_next([=](ChatHelpers::EmojiChosen data) {
|
||||||
|
if (question->hasFocus()) {
|
||||||
|
Ui::InsertEmojiAtCursor(question->textCursor(), data.emoji);
|
||||||
|
}
|
||||||
|
}, emojiToggle->lifetime());
|
||||||
|
emojiPanel->selector()->customEmojiChosen(
|
||||||
|
) | rpl::start_with_next([=](ChatHelpers::FileChosen data) {
|
||||||
|
if (question->hasFocus()) {
|
||||||
|
Data::InsertCustomEmoji(question, data.document);
|
||||||
|
}
|
||||||
|
}, emojiToggle->lifetime());
|
||||||
|
}
|
||||||
|
|
||||||
const auto warning = CreateWarningLabel(
|
const auto warning = CreateWarningLabel(
|
||||||
container,
|
container,
|
||||||
question,
|
question,
|
||||||
|
@ -916,9 +1100,10 @@ object_ptr<Ui::RpWidget> CreatePollBox::setupContent() {
|
||||||
st::defaultSubsectionTitle),
|
st::defaultSubsectionTitle),
|
||||||
st::createPollFieldTitlePadding);
|
st::createPollFieldTitlePadding);
|
||||||
const auto options = lifetime().make_state<Options>(
|
const auto options = lifetime().make_state<Options>(
|
||||||
getDelegate()->outerContainer(),
|
this,
|
||||||
container,
|
container,
|
||||||
&_controller->session(),
|
_controller,
|
||||||
|
_emojiPanel ? _emojiPanel.get() : nullptr,
|
||||||
(_chosen & PollData::Flag::Quiz));
|
(_chosen & PollData::Flag::Quiz));
|
||||||
auto limit = options->usedCount() | rpl::after_next([=](int count) {
|
auto limit = options->usedCount() | rpl::after_next([=](int count) {
|
||||||
setCloseByEscape(!count);
|
setCloseByEscape(!count);
|
||||||
|
|
|
@ -14,6 +14,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
struct PollData;
|
struct PollData;
|
||||||
|
|
||||||
|
namespace ChatHelpers {
|
||||||
|
class TabbedPanel;
|
||||||
|
} // namespace ChatHelpers
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class VerticalLayout;
|
class VerticalLayout;
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
@ -72,6 +76,7 @@ private:
|
||||||
const PollData::Flags _disabled = PollData::Flags();
|
const PollData::Flags _disabled = PollData::Flags();
|
||||||
const Api::SendType _sendType = Api::SendType();
|
const Api::SendType _sendType = Api::SendType();
|
||||||
const SendMenu::Type _sendMenuType;
|
const SendMenu::Type _sendMenuType;
|
||||||
|
base::unique_qptr<ChatHelpers::TabbedPanel> _emojiPanel;
|
||||||
Fn<void()> _setInnerFocus;
|
Fn<void()> _setInnerFocus;
|
||||||
Fn<rpl::producer<bool>()> _dataIsValidValue;
|
Fn<rpl::producer<bool>()> _dataIsValidValue;
|
||||||
rpl::event_stream<Result> _submitRequests;
|
rpl::event_stream<Result> _submitRequests;
|
||||||
|
|
Loading…
Add table
Reference in a new issue