|
|
|
@@ -402,6 +402,11 @@ private:
|
|
|
|
|
void showAddMenu(QPoint globalPos);
|
|
|
|
|
void startAddExistingStickerFlow();
|
|
|
|
|
void startCreateNewStickerFlow();
|
|
|
|
|
void startAddExistingEmojiFlow();
|
|
|
|
|
void startCreateNewEmojiFlow();
|
|
|
|
|
[[nodiscard]] ChatHelpers::TabbedPanel *createPickerPanel(
|
|
|
|
|
ChatHelpers::TabbedSelector::Mode mode,
|
|
|
|
|
uint64 excludeSetId);
|
|
|
|
|
|
|
|
|
|
void installDone(const MTPmessages_StickerSetInstallResult &result);
|
|
|
|
|
|
|
|
|
@@ -2426,11 +2431,16 @@ void StickerSetBox::Inner::repaintItems(crl::time now) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool StickerSetBox::Inner::hasAddCell() const {
|
|
|
|
|
return _loaded
|
|
|
|
|
&& _amSetCreator
|
|
|
|
|
&& (setType() == Data::StickersType::Stickers)
|
|
|
|
|
&& !_pack.isEmpty()
|
|
|
|
|
&& (_pack.size() < Api::kStickersInOwnedSetMax);
|
|
|
|
|
if (!_loaded || !_amSetCreator || _pack.isEmpty()) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
const auto type = setType();
|
|
|
|
|
if (type == Data::StickersType::Emoji) {
|
|
|
|
|
return (_pack.size() < Api::kEmojiInOwnedSetMax);
|
|
|
|
|
} else if (type == Data::StickersType::Stickers) {
|
|
|
|
|
return (_pack.size() < Api::kStickersInOwnedSetMax);
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int StickerSetBox::Inner::totalCellsCount() const {
|
|
|
|
@@ -2470,11 +2480,15 @@ void StickerSetBox::Inner::paintAddCell(QPainter &p) const {
|
|
|
|
|
ltrRect.height())
|
|
|
|
|
: ltrRect;
|
|
|
|
|
const auto center = rect::center(rect);
|
|
|
|
|
const auto bgRadius = isEmojiSet()
|
|
|
|
|
? st::emojiSetAddCellBgRadius
|
|
|
|
|
: st::stickersAddCellBgRadius;
|
|
|
|
|
const auto plusSize = isEmojiSet()
|
|
|
|
|
? st::emojiSetAddCellPlusSize
|
|
|
|
|
: st::stickersAddCellPlusSize;
|
|
|
|
|
const auto inner = QRect(
|
|
|
|
|
center - QPoint(
|
|
|
|
|
st::stickersAddCellBgRadius,
|
|
|
|
|
st::stickersAddCellBgRadius),
|
|
|
|
|
Size(st::stickersAddCellBgRadius * 2));
|
|
|
|
|
center - QPoint(bgRadius, bgRadius),
|
|
|
|
|
Size(bgRadius * 2));
|
|
|
|
|
|
|
|
|
|
auto hq = PainterHighQualityEnabler(p);
|
|
|
|
|
const auto base = st::windowSubTextFg->c;
|
|
|
|
@@ -2485,7 +2499,7 @@ void StickerSetBox::Inner::paintAddCell(QPainter &p) const {
|
|
|
|
|
p.setBrush(anim::with_alpha(base, bgAlpha));
|
|
|
|
|
p.drawEllipse(inner);
|
|
|
|
|
|
|
|
|
|
const auto plusHalf = st::stickersAddCellPlusSize / 2;
|
|
|
|
|
const auto plusHalf = plusSize / 2;
|
|
|
|
|
const auto thickness = st::stickersAddCellPlusThickness;
|
|
|
|
|
const auto plusH = QRectF(
|
|
|
|
|
center.x() - plusHalf,
|
|
|
|
@@ -2510,14 +2524,25 @@ void StickerSetBox::Inner::showAddMenu(QPoint globalPos) {
|
|
|
|
|
_menu = base::make_unique_q<Ui::PopupMenu>(
|
|
|
|
|
this,
|
|
|
|
|
st::popupMenuWithIcons);
|
|
|
|
|
_menu->addAction(
|
|
|
|
|
tr::lng_stickers_create_new(tr::now),
|
|
|
|
|
crl::guard(this, [=] { startCreateNewStickerFlow(); }),
|
|
|
|
|
&st::menuIconStickerCreate);
|
|
|
|
|
_menu->addAction(
|
|
|
|
|
tr::lng_stickers_add_existing(tr::now),
|
|
|
|
|
crl::guard(this, [=] { startAddExistingStickerFlow(); }),
|
|
|
|
|
&st::menuIconStickerAdd);
|
|
|
|
|
if (setType() == Data::StickersType::Emoji) {
|
|
|
|
|
_menu->addAction(
|
|
|
|
|
tr::lng_emoji_create_new(tr::now),
|
|
|
|
|
crl::guard(this, [=] { startCreateNewEmojiFlow(); }),
|
|
|
|
|
&st::menuIconStickerCreate);
|
|
|
|
|
_menu->addAction(
|
|
|
|
|
tr::lng_emoji_add_existing(tr::now),
|
|
|
|
|
crl::guard(this, [=] { startAddExistingEmojiFlow(); }),
|
|
|
|
|
&st::menuIconEmoji);
|
|
|
|
|
} else {
|
|
|
|
|
_menu->addAction(
|
|
|
|
|
tr::lng_stickers_create_new(tr::now),
|
|
|
|
|
crl::guard(this, [=] { startCreateNewStickerFlow(); }),
|
|
|
|
|
&st::menuIconStickerCreate);
|
|
|
|
|
_menu->addAction(
|
|
|
|
|
tr::lng_stickers_add_existing(tr::now),
|
|
|
|
|
crl::guard(this, [=] { startAddExistingStickerFlow(); }),
|
|
|
|
|
&st::menuIconStickerAdd);
|
|
|
|
|
}
|
|
|
|
|
_menu->popup(globalPos);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -2525,19 +2550,13 @@ void StickerSetBox::Inner::setOuterContainer(QPointer<QWidget> container) {
|
|
|
|
|
_outerContainer = std::move(container);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void StickerSetBox::Inner::startAddExistingStickerFlow() {
|
|
|
|
|
if (!hasAddCell() || !_outerContainer) {
|
|
|
|
|
return;
|
|
|
|
|
ChatHelpers::TabbedPanel *StickerSetBox::Inner::createPickerPanel(
|
|
|
|
|
ChatHelpers::TabbedSelector::Mode mode,
|
|
|
|
|
uint64 excludeSetId) {
|
|
|
|
|
if (!_outerContainer) {
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
const auto container = _outerContainer.data();
|
|
|
|
|
const auto identifier = StickerSetIdentifier{
|
|
|
|
|
.id = _setId,
|
|
|
|
|
.accessHash = _setAccessHash,
|
|
|
|
|
.shortName = _setShortName,
|
|
|
|
|
};
|
|
|
|
|
const auto session = _session;
|
|
|
|
|
const auto show = _show;
|
|
|
|
|
|
|
|
|
|
using Selector = ChatHelpers::TabbedSelector;
|
|
|
|
|
_pickerPanel = base::make_unique_q<ChatHelpers::TabbedPanel>(
|
|
|
|
|
container,
|
|
|
|
@@ -2548,8 +2567,8 @@ void StickerSetBox::Inner::startAddExistingStickerFlow() {
|
|
|
|
|
.show = _show,
|
|
|
|
|
.st = st::defaultComposeControls.tabbed,
|
|
|
|
|
.level = Window::GifPauseReason::Layer,
|
|
|
|
|
.mode = Selector::Mode::StickersOnly,
|
|
|
|
|
.excludeStickerSetId = _setId,
|
|
|
|
|
.mode = mode,
|
|
|
|
|
.excludeStickerSetId = excludeSetId,
|
|
|
|
|
}),
|
|
|
|
|
});
|
|
|
|
|
const auto panel = _pickerPanel.get();
|
|
|
|
@@ -2561,30 +2580,6 @@ void StickerSetBox::Inner::startAddExistingStickerFlow() {
|
|
|
|
|
panel->setShowAnimationOrigin(Ui::PanelAnimation::Origin::TopLeft);
|
|
|
|
|
panel->hide();
|
|
|
|
|
|
|
|
|
|
panel->selector()->fileChosen(
|
|
|
|
|
) | rpl::on_next([=, this](const ChatHelpers::FileChosen &chosen) {
|
|
|
|
|
const auto document = chosen.document;
|
|
|
|
|
if (_pickerPanel) {
|
|
|
|
|
_pickerPanel->hideAnimated();
|
|
|
|
|
}
|
|
|
|
|
const auto emoji = Api::StickerEmojiOrDefault(document);
|
|
|
|
|
Api::AddExistingStickerToSet(
|
|
|
|
|
session,
|
|
|
|
|
identifier,
|
|
|
|
|
document,
|
|
|
|
|
emoji,
|
|
|
|
|
crl::guard(this, [=, this](MTPmessages_StickerSet result) {
|
|
|
|
|
applySet(result);
|
|
|
|
|
show->showToast(
|
|
|
|
|
tr::lng_stickers_create_added(tr::now));
|
|
|
|
|
}),
|
|
|
|
|
crl::guard(this, [=](QString err) {
|
|
|
|
|
show->showToast(err.isEmpty()
|
|
|
|
|
? tr::lng_attach_failed(tr::now)
|
|
|
|
|
: err);
|
|
|
|
|
}));
|
|
|
|
|
}, panel->lifetime());
|
|
|
|
|
|
|
|
|
|
const auto reposition = [=] {
|
|
|
|
|
const auto size = container->size();
|
|
|
|
|
const auto margins = st::emojiPanMargins;
|
|
|
|
@@ -2607,6 +2602,91 @@ void StickerSetBox::Inner::startAddExistingStickerFlow() {
|
|
|
|
|
return base::EventFilterResult::Continue;
|
|
|
|
|
});
|
|
|
|
|
reposition();
|
|
|
|
|
return panel;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void StickerSetBox::Inner::startAddExistingStickerFlow() {
|
|
|
|
|
if (!hasAddCell()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
const auto panel = createPickerPanel(
|
|
|
|
|
ChatHelpers::TabbedSelector::Mode::StickersOnly,
|
|
|
|
|
_setId);
|
|
|
|
|
if (!panel) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
const auto identifier = StickerSetIdentifier{
|
|
|
|
|
.id = _setId,
|
|
|
|
|
.accessHash = _setAccessHash,
|
|
|
|
|
.shortName = _setShortName,
|
|
|
|
|
};
|
|
|
|
|
const auto session = _session;
|
|
|
|
|
const auto show = _show;
|
|
|
|
|
panel->selector()->fileChosen(
|
|
|
|
|
) | rpl::on_next([=, this](const ChatHelpers::FileChosen &chosen) {
|
|
|
|
|
const auto document = chosen.document;
|
|
|
|
|
if (_pickerPanel) {
|
|
|
|
|
_pickerPanel->hideAnimated();
|
|
|
|
|
}
|
|
|
|
|
const auto emoji = Api::StickerEmojiOrDefault(document);
|
|
|
|
|
Api::AddExistingStickerToSet(
|
|
|
|
|
session,
|
|
|
|
|
identifier,
|
|
|
|
|
document,
|
|
|
|
|
emoji,
|
|
|
|
|
crl::guard(this, [=, this](MTPmessages_StickerSet result) {
|
|
|
|
|
applySet(result);
|
|
|
|
|
show->showToast(
|
|
|
|
|
tr::lng_stickers_create_added(tr::now));
|
|
|
|
|
}),
|
|
|
|
|
crl::guard(this, [=](QString err) {
|
|
|
|
|
show->showToast(err.isEmpty()
|
|
|
|
|
? tr::lng_attach_failed(tr::now)
|
|
|
|
|
: err);
|
|
|
|
|
}));
|
|
|
|
|
}, panel->lifetime());
|
|
|
|
|
panel->showAnimated();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void StickerSetBox::Inner::startAddExistingEmojiFlow() {
|
|
|
|
|
if (!hasAddCell()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
const auto panel = createPickerPanel(
|
|
|
|
|
ChatHelpers::TabbedSelector::Mode::CustomEmojiOnly,
|
|
|
|
|
0);
|
|
|
|
|
if (!panel) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
const auto identifier = StickerSetIdentifier{
|
|
|
|
|
.id = _setId,
|
|
|
|
|
.accessHash = _setAccessHash,
|
|
|
|
|
.shortName = _setShortName,
|
|
|
|
|
};
|
|
|
|
|
const auto session = _session;
|
|
|
|
|
const auto show = _show;
|
|
|
|
|
panel->selector()->customEmojiChosen(
|
|
|
|
|
) | rpl::on_next([=, this](const ChatHelpers::FileChosen &chosen) {
|
|
|
|
|
const auto document = chosen.document;
|
|
|
|
|
if (_pickerPanel) {
|
|
|
|
|
_pickerPanel->hideAnimated();
|
|
|
|
|
}
|
|
|
|
|
const auto emoji = Api::StickerEmojiOrDefault(document);
|
|
|
|
|
Api::AddExistingStickerToSet(
|
|
|
|
|
session,
|
|
|
|
|
identifier,
|
|
|
|
|
document,
|
|
|
|
|
emoji,
|
|
|
|
|
crl::guard(this, [=, this](MTPmessages_StickerSet result) {
|
|
|
|
|
applySet(result);
|
|
|
|
|
show->showToast(tr::lng_emoji_added(tr::now));
|
|
|
|
|
}),
|
|
|
|
|
crl::guard(this, [=](QString err) {
|
|
|
|
|
show->showToast(err.isEmpty()
|
|
|
|
|
? tr::lng_attach_failed(tr::now)
|
|
|
|
|
: err);
|
|
|
|
|
}));
|
|
|
|
|
}, panel->lifetime());
|
|
|
|
|
panel->showAnimated();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -2626,4 +2706,20 @@ void StickerSetBox::Inner::startCreateNewStickerFlow() {
|
|
|
|
|
Api::OpenCreateStickerFlow(_show, identifier, onDone);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void StickerSetBox::Inner::startCreateNewEmojiFlow() {
|
|
|
|
|
if (!hasAddCell()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
const auto identifier = StickerSetIdentifier{
|
|
|
|
|
.id = _setId,
|
|
|
|
|
.accessHash = _setAccessHash,
|
|
|
|
|
.shortName = _setShortName,
|
|
|
|
|
};
|
|
|
|
|
const auto onDone = crl::guard(this, [=, this](
|
|
|
|
|
MTPmessages_StickerSet result) {
|
|
|
|
|
applySet(result);
|
|
|
|
|
});
|
|
|
|
|
Api::OpenCreateEmojiFlow(_show, identifier, onDone);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
StickerSetBox::Inner::~Inner() = default;
|
|
|
|
|