mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-16 06:07:06 +02:00
Insert / Copy emoji from pack preview.
This commit is contained in:
parent
cae18b3320
commit
bc340d75c4
23 changed files with 282 additions and 215 deletions
|
@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "apiwrap.h"
|
||||
#include "base/event_filter.h"
|
||||
#include "boxes/premium_limits_box.h"
|
||||
#include "boxes/premium_preview_box.h"
|
||||
#include "chat_helpers/emoji_suggestions_widget.h"
|
||||
#include "chat_helpers/message_field.h"
|
||||
#include "chat_helpers/tabbed_panel.h"
|
||||
|
@ -25,6 +26,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "data/data_session.h"
|
||||
#include "data/data_user.h"
|
||||
#include "data/data_premium_limits.h"
|
||||
#include "data/stickers/data_stickers.h"
|
||||
#include "data/stickers/data_custom_emoji.h"
|
||||
#include "editor/photo_editor_layer_widget.h"
|
||||
#include "history/history_drag_area.h"
|
||||
|
@ -502,14 +504,22 @@ void EditCaptionBox::setupEmojiPanel() {
|
|||
_emojiPanel->hide();
|
||||
_emojiPanel->selector()->setCurrentPeer(_historyItem->history()->peer);
|
||||
_emojiPanel->selector()->emojiChosen(
|
||||
) | rpl::start_with_next([=](Selector::EmojiChosen data) {
|
||||
) | rpl::start_with_next([=](ChatHelpers::EmojiChosen data) {
|
||||
Ui::InsertEmojiAtCursor(_field->textCursor(), data.emoji);
|
||||
}, lifetime());
|
||||
_emojiPanel->selector()->customEmojiChosen(
|
||||
) | rpl::start_with_next([=](Selector::FileChosen data) {
|
||||
Data::InsertCustomEmoji(_field.get(), data.document);
|
||||
) | rpl::start_with_next([=](ChatHelpers::FileChosen data) {
|
||||
const auto info = data.document->sticker();
|
||||
if (info
|
||||
&& info->setType == Data::StickersType::Emoji
|
||||
&& !_controller->session().premium()) {
|
||||
ShowPremiumPreviewBox(
|
||||
_controller,
|
||||
PremiumPreview::AnimatedEmoji);
|
||||
} else {
|
||||
Data::InsertCustomEmoji(_field.get(), data.document);
|
||||
}
|
||||
}, lifetime());
|
||||
_emojiPanel->selector()->showPromoForPremiumEmoji();
|
||||
|
||||
const auto filterCallback = [=](not_null<QEvent*> event) {
|
||||
emojiFilterForGeometry(event);
|
||||
|
|
|
@ -26,6 +26,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "core/mime_type.h"
|
||||
#include "base/event_filter.h"
|
||||
#include "boxes/premium_limits_box.h"
|
||||
#include "boxes/premium_preview_box.h"
|
||||
#include "ui/boxes/confirm_box.h"
|
||||
#include "ui/effects/animations.h"
|
||||
#include "ui/effects/scroll_content_shadow.h"
|
||||
|
@ -48,6 +49,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "data/data_document.h"
|
||||
#include "data/data_user.h"
|
||||
#include "data/data_premium_limits.h"
|
||||
#include "data/stickers/data_stickers.h"
|
||||
#include "data/stickers/data_custom_emoji.h"
|
||||
#include "media/clip/media_clip_reader.h"
|
||||
#include "api/api_common.h"
|
||||
|
@ -744,14 +746,23 @@ void SendFilesBox::setupEmojiPanel() {
|
|||
_emojiPanel->selector()->setAllowEmojiWithoutPremium(
|
||||
_allowEmojiWithoutPremium);
|
||||
_emojiPanel->selector()->emojiChosen(
|
||||
) | rpl::start_with_next([=](Selector::EmojiChosen data) {
|
||||
) | rpl::start_with_next([=](ChatHelpers::EmojiChosen data) {
|
||||
Ui::InsertEmojiAtCursor(_caption->textCursor(), data.emoji);
|
||||
}, lifetime());
|
||||
_emojiPanel->selector()->customEmojiChosen(
|
||||
) | rpl::start_with_next([=](Selector::FileChosen data) {
|
||||
Data::InsertCustomEmoji(_caption.data(), data.document);
|
||||
) | rpl::start_with_next([=](ChatHelpers::FileChosen data) {
|
||||
const auto info = data.document->sticker();
|
||||
if (info
|
||||
&& info->setType == Data::StickersType::Emoji
|
||||
&& !_controller->session().premium()
|
||||
&& !_allowEmojiWithoutPremium) {
|
||||
ShowPremiumPreviewBox(
|
||||
_controller,
|
||||
PremiumPreview::AnimatedEmoji);
|
||||
} else {
|
||||
Data::InsertCustomEmoji(_caption.data(), data.document);
|
||||
}
|
||||
}, lifetime());
|
||||
_emojiPanel->selector()->showPromoForPremiumEmoji();
|
||||
|
||||
const auto filterCallback = [=](not_null<QEvent*> event) {
|
||||
emojiFilterForGeometry(event);
|
||||
|
|
|
@ -154,6 +154,25 @@ void ValidatePremiumStarFg(QImage &image) {
|
|||
star.render(&p, outer);
|
||||
}
|
||||
|
||||
[[nodiscard]] TextForMimeData PrepareTextFromEmoji(
|
||||
not_null<DocumentData*> document) {
|
||||
const auto info = document->sticker();
|
||||
const auto text = info ? info->alt : QString();
|
||||
return {
|
||||
.expanded = text,
|
||||
.rich = {
|
||||
text,
|
||||
{
|
||||
EntityInText(
|
||||
EntityType::CustomEmoji,
|
||||
0,
|
||||
text.size(),
|
||||
Data::SerializeCustomEmojiId(document))
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
StickerPremiumMark::StickerPremiumMark(not_null<Main::Session*> session) {
|
||||
|
@ -264,6 +283,9 @@ private:
|
|||
|
||||
void visibleTopBottomUpdated(int visibleTop, int visibleBottom) override;
|
||||
|
||||
[[nodiscard]] Ui::MessageSendingAnimationFrom messageSentAnimationInfo(
|
||||
int index,
|
||||
not_null<DocumentData*> document) const;
|
||||
[[nodiscard]] QSize boundingBoxSize() const;
|
||||
|
||||
void paintSticker(
|
||||
|
@ -291,7 +313,10 @@ private:
|
|||
void gotSet(const MTPmessages_StickerSet &set);
|
||||
void installDone(const MTPmessages_StickerSetInstallResult &result);
|
||||
|
||||
void send(not_null<DocumentData*> sticker, Api::SendOptions options);
|
||||
void chosen(
|
||||
int index,
|
||||
not_null<DocumentData*> sticker,
|
||||
Api::SendOptions options);
|
||||
|
||||
not_null<Lottie::MultiPlayer*> getLottiePlayer();
|
||||
|
||||
|
@ -920,74 +945,113 @@ void StickerSetBox::Inner::mouseReleaseEvent(QMouseEvent *e) {
|
|||
}
|
||||
_previewTimer.cancel();
|
||||
const auto index = stickerFromGlobalPos(e->globalPos());
|
||||
if (index < 0
|
||||
|| index >= _pack.size()
|
||||
|| setType() != Data::StickersType::Stickers) {
|
||||
if (index < 0 || index >= _pack.size()) {
|
||||
return;
|
||||
}
|
||||
send(_pack[index], {});
|
||||
chosen(index, _pack[index], {});
|
||||
}
|
||||
|
||||
void StickerSetBox::Inner::send(
|
||||
void StickerSetBox::Inner::chosen(
|
||||
int index,
|
||||
not_null<DocumentData*> sticker,
|
||||
Api::SendOptions options) {
|
||||
const auto controller = _controller;
|
||||
const auto animation = options.scheduled
|
||||
? Ui::MessageSendingAnimationFrom()
|
||||
: messageSentAnimationInfo(index, sticker);
|
||||
Ui::PostponeCall(controller, [=] {
|
||||
if (controller->content()->sendExistingDocument(sticker, options)) {
|
||||
controller->window().hideSettingsAndLayer();
|
||||
}
|
||||
controller->stickerOrEmojiChosen({
|
||||
.document = sticker,
|
||||
.options = options,
|
||||
.messageSendingFrom = animation,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
auto StickerSetBox::Inner::messageSentAnimationInfo(
|
||||
int index,
|
||||
not_null<DocumentData*> document) const
|
||||
-> Ui::MessageSendingAnimationFrom {
|
||||
if (index < 0 || index >= _pack.size() || _pack[index] != document) {
|
||||
return {};
|
||||
}
|
||||
const auto row = index / _perRow;
|
||||
const auto column = index % _perRow;
|
||||
const auto left = _padding.left() + column * _singleSize.width();
|
||||
const auto top = _padding.top() + row * _singleSize.height();
|
||||
const auto rect = QRect(QPoint(left, top), _singleSize);
|
||||
const auto size = ChatHelpers::ComputeStickerSize(
|
||||
document,
|
||||
boundingBoxSize());
|
||||
const auto innerPos = QPoint(
|
||||
(rect.width() - size.width()) / 2,
|
||||
(rect.height() - size.height()) / 2);
|
||||
return {
|
||||
.type = Ui::MessageSendingAnimationFrom::Type::Sticker,
|
||||
.localId = _controller->session().data().nextLocalMessageId(),
|
||||
.globalStartGeometry = mapToGlobal(
|
||||
QRect(rect.topLeft() + innerPos, size)),
|
||||
};
|
||||
}
|
||||
|
||||
void StickerSetBox::Inner::contextMenuEvent(QContextMenuEvent *e) {
|
||||
const auto index = stickerFromGlobalPos(e->globalPos());
|
||||
if (index < 0
|
||||
|| index >= _pack.size()
|
||||
|| setType() != Data::StickersType::Stickers) {
|
||||
return;
|
||||
}
|
||||
const auto type = _controller->content()->sendMenuType();
|
||||
if (type == SendMenu::Type::Disabled) {
|
||||
|| setType() == Data::StickersType::Masks) {
|
||||
return;
|
||||
}
|
||||
_previewTimer.cancel();
|
||||
_menu = base::make_unique_q<Ui::PopupMenu>(
|
||||
this,
|
||||
st::popupMenuWithIcons);
|
||||
const auto type = _controller->content()->sendMenuType();
|
||||
if (setType() == Data::StickersType::Emoji) {
|
||||
if (const auto t = PrepareTextFromEmoji(_pack[index]); !t.empty()) {
|
||||
_menu->addAction(tr::lng_mediaview_copy(tr::now), [=] {
|
||||
if (auto data = TextUtilities::MimeDataFromText(t)) {
|
||||
QGuiApplication::clipboard()->setMimeData(data.release());
|
||||
}
|
||||
}, &st::menuIconCopy);
|
||||
}
|
||||
} else if (type != SendMenu::Type::Disabled) {
|
||||
const auto document = _pack[index];
|
||||
const auto sendSelected = [=](Api::SendOptions options) {
|
||||
chosen(index, document, options);
|
||||
};
|
||||
SendMenu::FillSendMenu(
|
||||
_menu.get(),
|
||||
type,
|
||||
SendMenu::DefaultSilentCallback(sendSelected),
|
||||
SendMenu::DefaultScheduleCallback(this, type, sendSelected));
|
||||
|
||||
const auto document = _pack[index];
|
||||
const auto sendSelected = [=](Api::SendOptions options) {
|
||||
send(document, options);
|
||||
};
|
||||
SendMenu::FillSendMenu(
|
||||
_menu.get(),
|
||||
type,
|
||||
SendMenu::DefaultSilentCallback(sendSelected),
|
||||
SendMenu::DefaultScheduleCallback(this, type, sendSelected));
|
||||
|
||||
const auto controller = _controller;
|
||||
const auto toggleFavedSticker = [=] {
|
||||
Api::ToggleFavedSticker(
|
||||
controller,
|
||||
document,
|
||||
Data::FileOriginStickerSet(Data::Stickers::FavedSetId, 0));
|
||||
};
|
||||
const auto isFaved = document->owner().stickers().isFaved(document);
|
||||
_menu->addAction(
|
||||
(isFaved
|
||||
? tr::lng_faved_stickers_remove
|
||||
: tr::lng_faved_stickers_add)(tr::now),
|
||||
toggleFavedSticker,
|
||||
(isFaved
|
||||
? &st::menuIconUnfave
|
||||
: &st::menuIconFave));
|
||||
|
||||
_menu->popup(QCursor::pos());
|
||||
const auto controller = _controller;
|
||||
const auto toggleFavedSticker = [=] {
|
||||
Api::ToggleFavedSticker(
|
||||
controller,
|
||||
document,
|
||||
Data::FileOriginStickerSet(Data::Stickers::FavedSetId, 0));
|
||||
};
|
||||
const auto isFaved = document->owner().stickers().isFaved(document);
|
||||
_menu->addAction(
|
||||
(isFaved
|
||||
? tr::lng_faved_stickers_remove
|
||||
: tr::lng_faved_stickers_add)(tr::now),
|
||||
toggleFavedSticker,
|
||||
(isFaved
|
||||
? &st::menuIconUnfave
|
||||
: &st::menuIconFave));
|
||||
}
|
||||
if (_menu->empty()) {
|
||||
_menu = nullptr;
|
||||
} else {
|
||||
_menu->popup(QCursor::pos());
|
||||
}
|
||||
}
|
||||
|
||||
void StickerSetBox::Inner::updateSelected() {
|
||||
auto selected = stickerFromGlobalPos(QCursor::pos());
|
||||
setSelected(setType() != Data::StickersType::Stickers ? -1 : selected);
|
||||
setSelected(setType() == Data::StickersType::Masks ? -1 : selected);
|
||||
}
|
||||
|
||||
void StickerSetBox::Inner::setSelected(int selected) {
|
||||
|
@ -1092,9 +1156,10 @@ uint64 StickerSetBox::Inner::setId() const {
|
|||
|
||||
QSize StickerSetBox::Inner::boundingBoxSize() const {
|
||||
if (isEmojiSet()) {
|
||||
const auto factor = style::DevicePixelRatio();
|
||||
const auto large = Ui::Emoji::GetSizeLarge() / factor;
|
||||
return QSize(large, large);
|
||||
using namespace Data;
|
||||
const auto size = FrameSizeFromTag(CustomEmojiSizeTag::Large)
|
||||
/ style::DevicePixelRatio();
|
||||
return { size, size };
|
||||
}
|
||||
return QSize(
|
||||
_singleSize.width() - st::roundRadiusSmall * 2,
|
||||
|
|
|
@ -46,8 +46,6 @@ constexpr auto kAppearDuration = 0.3;
|
|||
|
||||
using Core::RecentEmojiId;
|
||||
using Core::RecentEmojiDocument;
|
||||
using EmojiChosen = TabbedSelector::EmojiChosen;
|
||||
using FileChosen = TabbedSelector::FileChosen;
|
||||
|
||||
} // namespace
|
||||
|
||||
|
@ -504,10 +502,6 @@ rpl::producer<FileChosen> EmojiListWidget::customChosen() const {
|
|||
return _customChosen.events();
|
||||
}
|
||||
|
||||
rpl::producer<FileChosen> EmojiListWidget::premiumChosen() const {
|
||||
return _premiumChosen.events();
|
||||
}
|
||||
|
||||
rpl::producer<> EmojiListWidget::jumpedToPremium() const {
|
||||
return _jumpedToPremium.events();
|
||||
}
|
||||
|
@ -1294,14 +1288,9 @@ void EmojiListWidget::selectEmoji(EmojiChosen data) {
|
|||
|
||||
void EmojiListWidget::selectCustom(FileChosen data) {
|
||||
const auto document = data.document;
|
||||
if (document->isPremiumEmoji()
|
||||
&& !document->session().premium()
|
||||
&& !_allowWithoutPremium) {
|
||||
_premiumChosen.fire(std::move(data));
|
||||
return;
|
||||
}
|
||||
auto &settings = Core::App().settings();
|
||||
if (_mode == Mode::Full) {
|
||||
const auto skip = (document->isPremiumEmoji() && !session().premium());
|
||||
if (!skip && _mode == Mode::Full) {
|
||||
auto &settings = Core::App().settings();
|
||||
settings.incrementRecentEmoji({ RecentEmojiDocument{
|
||||
document->id,
|
||||
document->session().isTestMode(),
|
||||
|
|
|
@ -85,8 +85,6 @@ class EmojiListWidget
|
|||
, public Ui::AbstractTooltipShower {
|
||||
public:
|
||||
using Mode = EmojiListMode;
|
||||
using EmojiChosen = TabbedSelector::EmojiChosen;
|
||||
using FileChosen = TabbedSelector::FileChosen;
|
||||
|
||||
EmojiListWidget(
|
||||
QWidget *parent,
|
||||
|
@ -115,7 +113,6 @@ public:
|
|||
|
||||
[[nodiscard]] rpl::producer<EmojiChosen> chosen() const;
|
||||
[[nodiscard]] rpl::producer<FileChosen> customChosen() const;
|
||||
[[nodiscard]] rpl::producer<FileChosen> premiumChosen() const;
|
||||
[[nodiscard]] rpl::producer<> jumpedToPremium() const;
|
||||
|
||||
void provideRecent(const std::vector<DocumentId> &customRecentList);
|
||||
|
@ -382,7 +379,6 @@ private:
|
|||
|
||||
rpl::event_stream<EmojiChosen> _chosen;
|
||||
rpl::event_stream<FileChosen> _customChosen;
|
||||
rpl::event_stream<FileChosen> _premiumChosen;
|
||||
rpl::event_stream<> _jumpedToPremium;
|
||||
|
||||
};
|
||||
|
|
|
@ -19,6 +19,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "menu/menu_send.h" // SendMenu::FillSendMenu
|
||||
#include "chat_helpers/stickers_lottie.h"
|
||||
#include "chat_helpers/message_field.h" // PrepareMentionTag.
|
||||
#include "chat_helpers/tabbed_selector.h" // ChatHelpers::FileChosen.
|
||||
#include "mainwindow.h"
|
||||
#include "apiwrap.h"
|
||||
#include "api/api_chat_participants.h"
|
||||
|
@ -1127,7 +1128,7 @@ bool FieldAutocomplete::Inner::chooseAtIndex(
|
|||
};
|
||||
};
|
||||
|
||||
_stickerChosen.fire({ document, options, method, from() });
|
||||
_stickerChosen.fire({ document, options, from() });
|
||||
return true;
|
||||
}
|
||||
} else if (!_mrows->empty()) {
|
||||
|
|
|
@ -38,6 +38,9 @@ namespace SendMenu {
|
|||
enum class Type;
|
||||
} // namespace SendMenu
|
||||
|
||||
namespace ChatHelpers {
|
||||
struct FileChosen;
|
||||
} // namespace ChatHelpers
|
||||
|
||||
class FieldAutocomplete final : public Ui::RpWidget {
|
||||
public:
|
||||
|
@ -73,22 +76,17 @@ public:
|
|||
};
|
||||
struct MentionChosen {
|
||||
not_null<UserData*> user;
|
||||
ChooseMethod method;
|
||||
ChooseMethod method = ChooseMethod::ByEnter;
|
||||
};
|
||||
struct HashtagChosen {
|
||||
QString hashtag;
|
||||
ChooseMethod method;
|
||||
ChooseMethod method = ChooseMethod::ByEnter;
|
||||
};
|
||||
struct BotCommandChosen {
|
||||
QString command;
|
||||
ChooseMethod method;
|
||||
};
|
||||
struct StickerChosen {
|
||||
not_null<DocumentData*> sticker;
|
||||
Api::SendOptions options;
|
||||
ChooseMethod method;
|
||||
Ui::MessageSendingAnimationFrom messageSendingFrom;
|
||||
ChooseMethod method = ChooseMethod::ByEnter;
|
||||
};
|
||||
using StickerChosen = ChatHelpers::FileChosen;
|
||||
enum class Type {
|
||||
Mentions,
|
||||
Hashtags,
|
||||
|
|
|
@ -220,12 +220,11 @@ GifsListWidget::GifsListWidget(
|
|||
_mosaic.setRightSkip(st::inlineResultsSkip);
|
||||
}
|
||||
|
||||
rpl::producer<TabbedSelector::FileChosen> GifsListWidget::fileChosen() const {
|
||||
rpl::producer<FileChosen> GifsListWidget::fileChosen() const {
|
||||
return _fileChosen.events();
|
||||
}
|
||||
|
||||
auto GifsListWidget::photoChosen() const
|
||||
-> rpl::producer<TabbedSelector::PhotoChosen> {
|
||||
rpl::producer<PhotoChosen> GifsListWidget::photoChosen() const {
|
||||
return _photoChosen.events();
|
||||
}
|
||||
|
||||
|
|
|
@ -49,15 +49,13 @@ class GifsListWidget
|
|||
: public TabbedSelector::Inner
|
||||
, public InlineBots::Layout::Context {
|
||||
public:
|
||||
using InlineChosen = TabbedSelector::InlineChosen;
|
||||
|
||||
GifsListWidget(
|
||||
QWidget *parent,
|
||||
not_null<Window::SessionController*> controller,
|
||||
Window::GifPauseReason level);
|
||||
|
||||
rpl::producer<TabbedSelector::FileChosen> fileChosen() const;
|
||||
rpl::producer<TabbedSelector::PhotoChosen> photoChosen() const;
|
||||
rpl::producer<FileChosen> fileChosen() const;
|
||||
rpl::producer<PhotoChosen> photoChosen() const;
|
||||
rpl::producer<InlineChosen> inlineResultChosen() const;
|
||||
|
||||
void refreshRecent() override;
|
||||
|
@ -190,8 +188,8 @@ private:
|
|||
QString _inlineQuery, _inlineNextQuery, _inlineNextOffset;
|
||||
mtpRequestId _inlineRequestId = 0;
|
||||
|
||||
rpl::event_stream<TabbedSelector::FileChosen> _fileChosen;
|
||||
rpl::event_stream<TabbedSelector::PhotoChosen> _photoChosen;
|
||||
rpl::event_stream<FileChosen> _fileChosen;
|
||||
rpl::event_stream<PhotoChosen> _photoChosen;
|
||||
rpl::event_stream<InlineChosen> _inlineResultChosen;
|
||||
rpl::event_stream<> _cancelled;
|
||||
|
||||
|
|
|
@ -232,7 +232,7 @@ StickersListWidget::StickersListWidget(
|
|||
}, lifetime());
|
||||
}
|
||||
|
||||
rpl::producer<TabbedSelector::FileChosen> StickersListWidget::chosen() const {
|
||||
rpl::producer<FileChosen> StickersListWidget::chosen() const {
|
||||
return _chosen.events();
|
||||
}
|
||||
|
||||
|
|
|
@ -65,7 +65,7 @@ public:
|
|||
Window::GifPauseReason level,
|
||||
bool masks = false);
|
||||
|
||||
rpl::producer<TabbedSelector::FileChosen> chosen() const;
|
||||
rpl::producer<FileChosen> chosen() const;
|
||||
rpl::producer<> scrollUpdated() const;
|
||||
rpl::producer<TabbedSelector::Action> choosingUpdated() const;
|
||||
|
||||
|
@ -389,7 +389,7 @@ private:
|
|||
QString _searchQuery, _searchNextQuery;
|
||||
mtpRequestId _searchRequestId = 0;
|
||||
|
||||
rpl::event_stream<TabbedSelector::FileChosen> _chosen;
|
||||
rpl::event_stream<FileChosen> _chosen;
|
||||
rpl::event_stream<> _scrollUpdated;
|
||||
rpl::event_stream<TabbedSelector::Action> _choosingUpdated;
|
||||
|
||||
|
|
|
@ -492,21 +492,16 @@ bool TabbedSelector::hasMasksTab() const {
|
|||
return _hasMasksTab;
|
||||
}
|
||||
|
||||
auto TabbedSelector::emojiChosen() const -> rpl::producer<EmojiChosen> {
|
||||
rpl::producer<EmojiChosen> TabbedSelector::emojiChosen() const {
|
||||
return emoji()->chosen();
|
||||
}
|
||||
|
||||
auto TabbedSelector::customEmojiChosen() const -> rpl::producer<FileChosen> {
|
||||
rpl::producer<FileChosen> TabbedSelector::customEmojiChosen() const {
|
||||
return emoji()->customChosen();
|
||||
}
|
||||
|
||||
auto TabbedSelector::premiumEmojiChosen() const
|
||||
-> rpl::producer<FileChosen> {
|
||||
return emoji()->premiumChosen();
|
||||
}
|
||||
|
||||
auto TabbedSelector::fileChosen() const -> rpl::producer<FileChosen> {
|
||||
auto never = rpl::never<TabbedSelector::FileChosen>(
|
||||
rpl::producer<FileChosen> TabbedSelector::fileChosen() const {
|
||||
auto never = rpl::never<FileChosen>(
|
||||
) | rpl::type_erased();
|
||||
return rpl::merge(
|
||||
hasStickersTab() ? stickers()->chosen() : never,
|
||||
|
@ -514,8 +509,7 @@ auto TabbedSelector::fileChosen() const -> rpl::producer<FileChosen> {
|
|||
hasMasksTab() ? masks()->chosen() : never);
|
||||
}
|
||||
|
||||
auto TabbedSelector::photoChosen() const
|
||||
-> rpl::producer<TabbedSelector::PhotoChosen>{
|
||||
rpl::producer<PhotoChosen> TabbedSelector::photoChosen() const {
|
||||
return hasGifsTab() ? gifs()->photoChosen() : nullptr;
|
||||
}
|
||||
|
||||
|
@ -865,13 +859,6 @@ void TabbedSelector::setCurrentPeer(PeerData *peer) {
|
|||
peer && Data::AllowEmojiWithoutPremium(peer));
|
||||
}
|
||||
|
||||
void TabbedSelector::showPromoForPremiumEmoji() {
|
||||
premiumEmojiChosen(
|
||||
) | rpl::start_with_next([=] {
|
||||
ShowPremiumPreviewBox(_controller, PremiumPreview::AnimatedEmoji);
|
||||
}, lifetime());
|
||||
}
|
||||
|
||||
void TabbedSelector::provideRecentEmoji(
|
||||
const std::vector<DocumentId> &customRecentList) {
|
||||
for (const auto &tab : _tabs) {
|
||||
|
|
|
@ -47,6 +47,10 @@ struct EmojiPan;
|
|||
|
||||
namespace ChatHelpers {
|
||||
|
||||
class EmojiListWidget;
|
||||
class StickersListWidget;
|
||||
class GifsListWidget;
|
||||
|
||||
enum class SelectorTab {
|
||||
Emoji,
|
||||
Stickers,
|
||||
|
@ -54,27 +58,27 @@ enum class SelectorTab {
|
|||
Masks,
|
||||
};
|
||||
|
||||
class EmojiListWidget;
|
||||
class StickersListWidget;
|
||||
class GifsListWidget;
|
||||
struct FileChosen {
|
||||
not_null<DocumentData*> document;
|
||||
Api::SendOptions options;
|
||||
Ui::MessageSendingAnimationFrom messageSendingFrom;
|
||||
};
|
||||
|
||||
struct PhotoChosen {
|
||||
not_null<PhotoData*> photo;
|
||||
Api::SendOptions options;
|
||||
};
|
||||
|
||||
struct EmojiChosen {
|
||||
EmojiPtr emoji;
|
||||
Ui::MessageSendingAnimationFrom messageSendingFrom;
|
||||
};
|
||||
|
||||
using InlineChosen = InlineBots::ResultSelected;
|
||||
|
||||
class TabbedSelector : public Ui::RpWidget {
|
||||
public:
|
||||
static constexpr auto kPickCustomTimeId = -1;
|
||||
struct FileChosen {
|
||||
not_null<DocumentData*> document;
|
||||
Api::SendOptions options;
|
||||
Ui::MessageSendingAnimationFrom messageSendingFrom;
|
||||
};
|
||||
struct PhotoChosen {
|
||||
not_null<PhotoData*> photo;
|
||||
Api::SendOptions options;
|
||||
};
|
||||
struct EmojiChosen {
|
||||
EmojiPtr emoji;
|
||||
Ui::MessageSendingAnimationFrom messageSendingFrom;
|
||||
};
|
||||
using InlineChosen = InlineBots::ResultSelected;
|
||||
enum class Mode {
|
||||
Full,
|
||||
EmojiOnly,
|
||||
|
@ -98,7 +102,6 @@ public:
|
|||
|
||||
rpl::producer<EmojiChosen> emojiChosen() const;
|
||||
rpl::producer<FileChosen> customEmojiChosen() const;
|
||||
rpl::producer<FileChosen> premiumEmojiChosen() const;
|
||||
rpl::producer<FileChosen> fileChosen() const;
|
||||
rpl::producer<PhotoChosen> photoChosen() const;
|
||||
rpl::producer<InlineChosen> inlineResultChosen() const;
|
||||
|
@ -113,7 +116,6 @@ public:
|
|||
void setRoundRadius(int radius);
|
||||
void refreshStickers();
|
||||
void setCurrentPeer(PeerData *peer);
|
||||
void showPromoForPremiumEmoji();
|
||||
void provideRecentEmoji(const std::vector<DocumentId> &customRecentList);
|
||||
|
||||
void hideFinished();
|
||||
|
|
|
@ -37,7 +37,7 @@ StickersPanelController::StickersPanelController(
|
|||
auto StickersPanelController::stickerChosen() const
|
||||
-> rpl::producer<not_null<DocumentData*>> {
|
||||
return _stickersPanel->selector()->fileChosen(
|
||||
) | rpl::map([](const ChatHelpers::TabbedSelector::FileChosen &data) {
|
||||
) | rpl::map([](const ChatHelpers::FileChosen &data) {
|
||||
return data.document;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -423,14 +423,6 @@ HistoryWidget::HistoryWidget(
|
|||
insertHashtagOrBotCommand(data.command, data.method);
|
||||
}, lifetime());
|
||||
|
||||
_fieldAutocomplete->stickerChosen(
|
||||
) | rpl::start_with_next([=](FieldAutocomplete::StickerChosen data) {
|
||||
controller->sendingAnimation().appendSending(
|
||||
data.messageSendingFrom);
|
||||
const auto localId = data.messageSendingFrom.localId;
|
||||
sendExistingDocument(data.sticker, data.options, localId);
|
||||
}, lifetime());
|
||||
|
||||
_fieldAutocomplete->setModerateKeyActivateCallback([=](int key) {
|
||||
const auto context = [=](FullMsgId itemId) {
|
||||
return _list->prepareClickContext(Qt::LeftButton, itemId);
|
||||
|
@ -1067,48 +1059,48 @@ void HistoryWidget::initTabbedSelector() {
|
|||
selector->emojiChosen(
|
||||
) | rpl::filter([=] {
|
||||
return !isHidden() && !_field->isHidden();
|
||||
}) | rpl::start_with_next([=](Selector::EmojiChosen data) {
|
||||
}) | rpl::start_with_next([=](ChatHelpers::EmojiChosen data) {
|
||||
Ui::InsertEmojiAtCursor(_field->textCursor(), data.emoji);
|
||||
}, lifetime());
|
||||
|
||||
selector->customEmojiChosen(
|
||||
) | rpl::filter([=] {
|
||||
return !isHidden() && !_field->isHidden();
|
||||
}) | rpl::start_with_next([=](Selector::FileChosen data) {
|
||||
Data::InsertCustomEmoji(_field.data(), data.document);
|
||||
}, lifetime());
|
||||
|
||||
selector->premiumEmojiChosen(
|
||||
) | rpl::filter([=] {
|
||||
return !isHidden() && !_field->isHidden();
|
||||
}) | rpl::start_with_next([=](Selector::FileChosen data) {
|
||||
showPremiumToast(data.document);
|
||||
}, lifetime());
|
||||
|
||||
selector->fileChosen(
|
||||
) | filter | rpl::start_with_next([=](Selector::FileChosen data) {
|
||||
controller()->sendingAnimation().appendSending(
|
||||
data.messageSendingFrom);
|
||||
sendExistingDocument(
|
||||
data.document,
|
||||
data.options,
|
||||
data.messageSendingFrom.localId);
|
||||
rpl::merge(
|
||||
selector->fileChosen() | filter,
|
||||
_fieldAutocomplete->stickerChosen(),
|
||||
selector->customEmojiChosen() | filter,
|
||||
controller()->stickerOrEmojiChosen() | filter
|
||||
) | rpl::start_with_next([=](ChatHelpers::FileChosen data) {
|
||||
controller()->hideLayer(anim::type::normal);
|
||||
if (const auto info = data.document->sticker()
|
||||
; info && info->setType == Data::StickersType::Emoji) {
|
||||
if (data.document->isPremiumEmoji()
|
||||
&& !session().premium()
|
||||
&& (!_peer || !Data::AllowEmojiWithoutPremium(_peer))) {
|
||||
showPremiumToast(data.document);
|
||||
} else if (!_field->isHidden()) {
|
||||
Data::InsertCustomEmoji(_field.data(), data.document);
|
||||
}
|
||||
} else {
|
||||
controller()->sendingAnimation().appendSending(
|
||||
data.messageSendingFrom);
|
||||
const auto localId = data.messageSendingFrom.localId;
|
||||
sendExistingDocument(data.document, data.options, localId);
|
||||
}
|
||||
}, lifetime());
|
||||
|
||||
selector->photoChosen(
|
||||
) | filter | rpl::start_with_next([=](Selector::PhotoChosen data) {
|
||||
) | filter | rpl::start_with_next([=](ChatHelpers::PhotoChosen data) {
|
||||
sendExistingPhoto(data.photo, data.options);
|
||||
}, lifetime());
|
||||
|
||||
selector->inlineResultChosen(
|
||||
) | filter | rpl::filter([=](const Selector::InlineChosen &data) {
|
||||
) | filter | rpl::filter([=](const ChatHelpers::InlineChosen &data) {
|
||||
if (!data.recipientOverride) {
|
||||
return true;
|
||||
} else if (data.recipientOverride != _peer) {
|
||||
showHistory(data.recipientOverride->id, ShowAtTheEndMsgId);
|
||||
}
|
||||
return (data.recipientOverride == _peer);
|
||||
}) | rpl::start_with_next([=](Selector::InlineChosen data) {
|
||||
}) | rpl::start_with_next([=](ChatHelpers::InlineChosen data) {
|
||||
sendInlineResult(data);
|
||||
}, lifetime());
|
||||
|
||||
|
|
|
@ -1072,7 +1072,7 @@ rpl::producer<PhotoChosen> ComposeControls::photoChosen() const {
|
|||
}
|
||||
|
||||
auto ComposeControls::inlineResultChosen() const
|
||||
->rpl::producer<ChatHelpers::TabbedSelector::InlineChosen> {
|
||||
-> rpl::producer<InlineChosen> {
|
||||
return _inlineResultChosen.events();
|
||||
}
|
||||
|
||||
|
@ -1525,11 +1525,7 @@ void ComposeControls::initAutocomplete() {
|
|||
//_saveDraftStart = crl::now();
|
||||
//saveDraft();
|
||||
//saveCloudDraft(); // won't be needed if SendInlineBotResult will clear the cloud draft
|
||||
_fileChosen.fire(FileChosen{
|
||||
.document = data.sticker,
|
||||
.options = data.options,
|
||||
.messageSendingFrom = base::take(data.messageSendingFrom),
|
||||
});
|
||||
_fileChosen.fire(std::move(data));
|
||||
}, _autocomplete->lifetime());
|
||||
|
||||
_autocomplete->choosingProcesses(
|
||||
|
@ -1857,28 +1853,33 @@ void ComposeControls::initTabbedSelector() {
|
|||
return base::EventFilterResult::Continue;
|
||||
});
|
||||
|
||||
using EmojiChosen = ChatHelpers::TabbedSelector::EmojiChosen;
|
||||
selector->emojiChosen(
|
||||
) | rpl::start_with_next([=](EmojiChosen data) {
|
||||
) | rpl::start_with_next([=](ChatHelpers::EmojiChosen data) {
|
||||
Ui::InsertEmojiAtCursor(_field->textCursor(), data.emoji);
|
||||
}, wrap->lifetime());
|
||||
|
||||
using FileChosen = ChatHelpers::TabbedSelector::FileChosen;
|
||||
selector->customEmojiChosen(
|
||||
) | rpl::start_with_next([=](FileChosen data) {
|
||||
Data::InsertCustomEmoji(_field, data.document);
|
||||
}, wrap->lifetime());
|
||||
|
||||
selector->premiumEmojiChosen(
|
||||
) | rpl::start_with_next([=](FileChosen data) {
|
||||
if (_unavailableEmojiPasted) {
|
||||
_unavailableEmojiPasted(data.document);
|
||||
rpl::merge(
|
||||
selector->fileChosen(),
|
||||
selector->customEmojiChosen(),
|
||||
_window->stickerOrEmojiChosen()
|
||||
) | rpl::start_with_next([=](ChatHelpers::FileChosen &&data) {
|
||||
if (const auto info = data.document->sticker()
|
||||
; info && info->setType == Data::StickersType::Emoji) {
|
||||
if (data.document->isPremiumEmoji()
|
||||
&& !session().premium()
|
||||
&& (!_history
|
||||
|| !Data::AllowEmojiWithoutPremium(_history->peer))) {
|
||||
if (_unavailableEmojiPasted) {
|
||||
_unavailableEmojiPasted(data.document);
|
||||
}
|
||||
} else {
|
||||
Data::InsertCustomEmoji(_field, data.document);
|
||||
}
|
||||
} else {
|
||||
_fileChosen.fire(std::move(data));
|
||||
}
|
||||
}, wrap->lifetime());
|
||||
|
||||
selector->fileChosen(
|
||||
) | rpl::start_to_stream(_fileChosen, wrap->lifetime());
|
||||
|
||||
selector->photoChosen(
|
||||
) | rpl::start_to_stream(_photoChosen, wrap->lifetime());
|
||||
|
||||
|
|
|
@ -16,7 +16,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/rp_widget.h"
|
||||
#include "ui/effects/animations.h"
|
||||
#include "ui/widgets/input_fields.h"
|
||||
#include "chat_helpers/tabbed_selector.h"
|
||||
|
||||
class History;
|
||||
class FieldAutocomplete;
|
||||
|
@ -28,6 +27,8 @@ enum class Type;
|
|||
namespace ChatHelpers {
|
||||
class TabbedPanel;
|
||||
class TabbedSelector;
|
||||
struct FileChosen;
|
||||
struct PhotoChosen;
|
||||
} // namespace ChatHelpers
|
||||
|
||||
namespace Data {
|
||||
|
@ -43,6 +44,7 @@ class ItemBase;
|
|||
class Widget;
|
||||
} // namespace Layout
|
||||
class Result;
|
||||
struct ResultSelected;
|
||||
} // namespace InlineBots
|
||||
|
||||
namespace Ui {
|
||||
|
@ -78,9 +80,9 @@ class WebpageProcessor;
|
|||
|
||||
class ComposeControls final {
|
||||
public:
|
||||
using FileChosen = ChatHelpers::TabbedSelector::FileChosen;
|
||||
using PhotoChosen = ChatHelpers::TabbedSelector::PhotoChosen;
|
||||
using InlineChosen = ChatHelpers::TabbedSelector::InlineChosen;
|
||||
using FileChosen = ChatHelpers::FileChosen;
|
||||
using PhotoChosen = ChatHelpers::PhotoChosen;
|
||||
using InlineChosen = InlineBots::ResultSelected;
|
||||
|
||||
using MessageToEdit = Controls::MessageToEdit;
|
||||
using VoiceToSend = Controls::VoiceToSend;
|
||||
|
|
|
@ -18,6 +18,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "history/history_item_components.h"
|
||||
#include "history/history_item.h"
|
||||
#include "menu/menu_send.h" // SendMenu::Type.
|
||||
#include "ui/chat/attach/attach_prepare.h"
|
||||
#include "ui/chat/attach/attach_send_files_way.h"
|
||||
#include "ui/chat/pinned_bar.h"
|
||||
#include "ui/chat/chat_style.h"
|
||||
#include "ui/widgets/scroll_area.h"
|
||||
|
@ -28,8 +30,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/toast/toast.h"
|
||||
#include "ui/text/format_values.h"
|
||||
#include "ui/text/text_utilities.h"
|
||||
#include "ui/chat/attach/attach_prepare.h"
|
||||
#include "ui/chat/attach/attach_send_files_way.h"
|
||||
#include "ui/effects/message_sending_animation_controller.h"
|
||||
#include "ui/special_buttons.h"
|
||||
#include "ui/ui_utility.h"
|
||||
|
@ -40,6 +40,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "api/api_sending.h"
|
||||
#include "apiwrap.h"
|
||||
#include "ui/boxes/confirm_box.h"
|
||||
#include "chat_helpers/tabbed_selector.h"
|
||||
#include "boxes/delete_messages_box.h"
|
||||
#include "boxes/edit_caption_box.h"
|
||||
#include "boxes/send_files_box.h"
|
||||
|
@ -573,22 +574,21 @@ void RepliesWidget::setupComposeControls() {
|
|||
using Selector = ChatHelpers::TabbedSelector;
|
||||
|
||||
_composeControls->fileChosen(
|
||||
) | rpl::start_with_next([=](Selector::FileChosen chosen) {
|
||||
) | rpl::start_with_next([=](ChatHelpers::FileChosen data) {
|
||||
controller()->hideLayer(anim::type::normal);
|
||||
controller()->sendingAnimation().appendSending(
|
||||
chosen.messageSendingFrom);
|
||||
sendExistingDocument(
|
||||
chosen.document,
|
||||
chosen.options,
|
||||
chosen.messageSendingFrom.localId);
|
||||
data.messageSendingFrom);
|
||||
const auto localId = data.messageSendingFrom.localId;
|
||||
sendExistingDocument(data.document, data.options, localId);
|
||||
}, lifetime());
|
||||
|
||||
_composeControls->photoChosen(
|
||||
) | rpl::start_with_next([=](Selector::PhotoChosen chosen) {
|
||||
) | rpl::start_with_next([=](ChatHelpers::PhotoChosen chosen) {
|
||||
sendExistingPhoto(chosen.photo, chosen.options);
|
||||
}, lifetime());
|
||||
|
||||
_composeControls->inlineResultChosen(
|
||||
) | rpl::start_with_next([=](Selector::InlineChosen chosen) {
|
||||
) | rpl::start_with_next([=](ChatHelpers::InlineChosen chosen) {
|
||||
controller()->sendingAnimation().appendSending(
|
||||
chosen.messageSendingFrom);
|
||||
const auto localId = chosen.messageSendingFrom.localId;
|
||||
|
|
|
@ -45,6 +45,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "base/call_delayed.h"
|
||||
#include "base/qt/qt_key_modifiers.h"
|
||||
#include "core/file_utilities.h"
|
||||
#include "chat_helpers/tabbed_selector.h"
|
||||
#include "main/main_session.h"
|
||||
#include "data/data_chat_participant_status.h"
|
||||
#include "data/data_session.h"
|
||||
|
@ -263,17 +264,18 @@ void ScheduledWidget::setupComposeControls() {
|
|||
using Selector = ChatHelpers::TabbedSelector;
|
||||
|
||||
_composeControls->fileChosen(
|
||||
) | rpl::start_with_next([=](Selector::FileChosen chosen) {
|
||||
sendExistingDocument(chosen.document);
|
||||
) | rpl::start_with_next([=](ChatHelpers::FileChosen data) {
|
||||
controller()->hideLayer(anim::type::normal);
|
||||
sendExistingDocument(data.document);
|
||||
}, lifetime());
|
||||
|
||||
_composeControls->photoChosen(
|
||||
) | rpl::start_with_next([=](Selector::PhotoChosen chosen) {
|
||||
) | rpl::start_with_next([=](ChatHelpers::PhotoChosen chosen) {
|
||||
sendExistingPhoto(chosen.photo);
|
||||
}, lifetime());
|
||||
|
||||
_composeControls->inlineResultChosen(
|
||||
) | rpl::start_with_next([=](Selector::InlineChosen chosen) {
|
||||
) | rpl::start_with_next([=](ChatHelpers::InlineChosen chosen) {
|
||||
sendInlineResult(chosen.result, chosen.bot);
|
||||
}, lifetime());
|
||||
|
||||
|
|
|
@ -778,10 +778,8 @@ void Selector::createList(not_null<Window::SessionController*> controller) {
|
|||
})
|
||||
).data();
|
||||
|
||||
rpl::merge(
|
||||
_list->customChosen(),
|
||||
_list->premiumChosen()
|
||||
) | rpl::start_with_next([=](TabbedSelector::FileChosen data) {
|
||||
_list->customChosen(
|
||||
) | rpl::start_with_next([=](ChatHelpers::FileChosen data) {
|
||||
const auto id = DocumentId{ data.document->id };
|
||||
const auto i = defaultReactionIds.find(id);
|
||||
const auto reactionId = (i != end(defaultReactionIds))
|
||||
|
|
|
@ -19,6 +19,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/boxes/time_picker_box.h"
|
||||
#include "ui/text/format_values.h"
|
||||
#include "base/unixtime.h"
|
||||
#include "boxes/premium_preview_box.h"
|
||||
#include "window/window_session_controller.h"
|
||||
#include "window/window_controller.h"
|
||||
#include "main/main_session.h"
|
||||
|
@ -246,7 +247,6 @@ void EmojiStatusPanel::create(
|
|||
st::emojiPanMinHeight / 2,
|
||||
st::emojiPanMinHeight);
|
||||
_panel->hide();
|
||||
_panel->selector()->setAllowEmojiWithoutPremium(false);
|
||||
|
||||
struct Chosen {
|
||||
DocumentId id = 0;
|
||||
|
@ -260,7 +260,7 @@ void EmojiStatusPanel::create(
|
|||
}, _panel->lifetime());
|
||||
|
||||
auto statusChosen = _panel->selector()->customEmojiChosen(
|
||||
) | rpl::map([=](Selector::FileChosen data) {
|
||||
) | rpl::map([=](ChatHelpers::FileChosen data) {
|
||||
return Chosen{
|
||||
.id = data.document->id,
|
||||
.until = data.options.scheduled,
|
||||
|
@ -269,7 +269,7 @@ void EmojiStatusPanel::create(
|
|||
});
|
||||
|
||||
auto emojiChosen = _panel->selector()->emojiChosen(
|
||||
) | rpl::map([=](Selector::EmojiChosen data) {
|
||||
) | rpl::map([=](ChatHelpers::EmojiChosen data) {
|
||||
return Chosen{ .animation = data.messageSendingFrom };
|
||||
});
|
||||
|
||||
|
@ -285,7 +285,9 @@ void EmojiStatusPanel::create(
|
|||
std::move(statusChosen),
|
||||
std::move(emojiChosen)
|
||||
) | rpl::start_with_next([=](const Chosen chosen) {
|
||||
if (chosen.until == Selector::kPickCustomTimeId) {
|
||||
if (chosen.id && !controller->session().premium()) {
|
||||
ShowPremiumPreviewBox(controller, PremiumPreview::EmojiStatus);
|
||||
} else if (chosen.until == Selector::kPickCustomTimeId) {
|
||||
_panel->hideAnimated();
|
||||
controller->show(Box(PickUntilBox, [=](TimeId seconds) {
|
||||
set({ chosen.id, base::unixtime::now() + seconds });
|
||||
|
@ -295,8 +297,6 @@ void EmojiStatusPanel::create(
|
|||
_panel->hideAnimated();
|
||||
}
|
||||
}, _panel->lifetime());
|
||||
|
||||
_panel->selector()->showPromoForPremiumEmoji();
|
||||
}
|
||||
|
||||
void EmojiStatusPanel::startAnimation(
|
||||
|
|
|
@ -1611,6 +1611,15 @@ rpl::producer<int> SessionController::connectingBottomSkipValue() const {
|
|||
return _connectingBottomSkip.value();
|
||||
}
|
||||
|
||||
void SessionController::stickerOrEmojiChosen(FileChosen chosen) {
|
||||
_stickerOrEmojiChosen.fire(std::move(chosen));
|
||||
}
|
||||
|
||||
auto SessionController::stickerOrEmojiChosen() const
|
||||
-> rpl::producer<FileChosen> {
|
||||
return _stickerOrEmojiChosen.events();
|
||||
}
|
||||
|
||||
QPointer<Ui::BoxContent> SessionController::show(
|
||||
object_ptr<Ui::BoxContent> content,
|
||||
Ui::LayerOptions options,
|
||||
|
|
|
@ -32,6 +32,7 @@ enum class WindowLayout;
|
|||
namespace ChatHelpers {
|
||||
class TabbedSelector;
|
||||
class EmojiInteractions;
|
||||
struct FileChosen;
|
||||
} // namespace ChatHelpers
|
||||
|
||||
namespace Main {
|
||||
|
@ -317,6 +318,10 @@ public:
|
|||
void setConnectingBottomSkip(int skip);
|
||||
rpl::producer<int> connectingBottomSkipValue() const;
|
||||
|
||||
using FileChosen = ChatHelpers::FileChosen;
|
||||
void stickerOrEmojiChosen(FileChosen chosen);
|
||||
[[nodiscard]] rpl::producer<FileChosen> stickerOrEmojiChosen() const;
|
||||
|
||||
QPointer<Ui::BoxContent> show(
|
||||
object_ptr<Ui::BoxContent> content,
|
||||
Ui::LayerOptions options = Ui::LayerOption::KeepOther,
|
||||
|
@ -585,6 +590,8 @@ private:
|
|||
|
||||
rpl::variable<int> _connectingBottomSkip;
|
||||
|
||||
rpl::event_stream<ChatHelpers::FileChosen> _stickerOrEmojiChosen;
|
||||
|
||||
PeerData *_showEditPeer = nullptr;
|
||||
rpl::variable<Data::Folder*> _openedFolder;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue