mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2026-07-25 06:54:43 +00:00
Added Add-to-Sticker-Set submenu for stickers from foreign packs.
This commit is contained in:
@@ -4514,6 +4514,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||||||
|
|
||||||
"lng_stickers_create_new" = "Create a New Sticker";
|
"lng_stickers_create_new" = "Create a New Sticker";
|
||||||
"lng_stickers_add_existing" = "Add an Existing Sticker";
|
"lng_stickers_add_existing" = "Add an Existing Sticker";
|
||||||
|
"lng_stickers_add_to_set" = "Add to Sticker Set";
|
||||||
|
"lng_stickers_already_in_set" = "This Sticker is already in the Set.";
|
||||||
|
"lng_stickers_set_is_full" = "This Sticker Set is full.";
|
||||||
"lng_stickers_pack_choose_emoji_title" = "Choose Emoji";
|
"lng_stickers_pack_choose_emoji_title" = "Choose Emoji";
|
||||||
"lng_stickers_pack_choose_emoji_about" = "Pick an emoji that corresponds to this sticker.";
|
"lng_stickers_pack_choose_emoji_about" = "Pick an emoji that corresponds to this sticker.";
|
||||||
"lng_stickers_pick_existing_title" = "Choose Sticker";
|
"lng_stickers_pick_existing_title" = "Choose Sticker";
|
||||||
|
|||||||
@@ -10,13 +10,23 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||||||
#include "apiwrap.h"
|
#include "apiwrap.h"
|
||||||
#include "base/random.h"
|
#include "base/random.h"
|
||||||
#include "base/unixtime.h"
|
#include "base/unixtime.h"
|
||||||
|
#include "chat_helpers/compose/compose_show.h"
|
||||||
#include "data/data_document.h"
|
#include "data/data_document.h"
|
||||||
|
#include "data/data_file_origin.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "data/stickers/data_stickers.h"
|
#include "data/stickers/data_stickers.h"
|
||||||
#include "data/stickers/data_stickers_set.h"
|
#include "data/stickers/data_stickers_set.h"
|
||||||
|
#include "lang/lang_keys.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
|
#include "menu/menu_action_with_thumbnail.h"
|
||||||
#include "storage/file_upload.h"
|
#include "storage/file_upload.h"
|
||||||
#include "storage/localimageloader.h"
|
#include "storage/localimageloader.h"
|
||||||
|
#include "styles/style_menu_icons.h"
|
||||||
|
#include "styles/style_widgets.h"
|
||||||
|
#include "ui/dynamic_thumbnails.h"
|
||||||
|
#include "ui/widgets/menu/menu_add_action_callback.h"
|
||||||
|
#include "ui/widgets/menu/menu_common.h"
|
||||||
|
#include "ui/widgets/popup_menu.h"
|
||||||
|
|
||||||
namespace Api {
|
namespace Api {
|
||||||
namespace {
|
namespace {
|
||||||
@@ -81,6 +91,35 @@ void FeedSetIfFull(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename Callback>
|
||||||
|
void EnumerateOwnedStickerSets(
|
||||||
|
not_null<Main::Session*> session,
|
||||||
|
Callback &&callback) {
|
||||||
|
const auto &stickers = session->data().stickers();
|
||||||
|
const auto &sets = stickers.sets();
|
||||||
|
for (const auto setId : stickers.setsOrder()) {
|
||||||
|
const auto it = sets.find(setId);
|
||||||
|
if (it == sets.end()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const auto set = it->second.get();
|
||||||
|
if (!(set->flags & Data::StickersSetFlag::AmCreator)
|
||||||
|
|| (set->type() != Data::StickersType::Stickers)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
using namespace Data;
|
||||||
|
if constexpr (std::is_same_v<
|
||||||
|
bool,
|
||||||
|
std::invoke_result_t<Callback, not_null<StickersSet*>>>) {
|
||||||
|
if (!callback(set)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
callback(set);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void AddExistingStickerToSet(
|
void AddExistingStickerToSet(
|
||||||
@@ -105,6 +144,104 @@ void AddExistingStickerToSet(
|
|||||||
}).handleFloodErrors().send();
|
}).handleFloodErrors().send();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString StickerEmojiOrDefault(not_null<DocumentData*> document) {
|
||||||
|
if (const auto sticker = document->sticker()) {
|
||||||
|
if (!sticker->alt.isEmpty()) {
|
||||||
|
return sticker->alt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return QString::fromUtf8("\xF0\x9F\x99\x82");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HasOwnedStickerSets(not_null<Main::Session*> session) {
|
||||||
|
auto found = false;
|
||||||
|
EnumerateOwnedStickerSets(session, [&](not_null<Data::StickersSet*>) {
|
||||||
|
found = true;
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FillChooseStickerSetMenu(
|
||||||
|
not_null<Ui::PopupMenu*> menu,
|
||||||
|
std::shared_ptr<ChatHelpers::Show> show,
|
||||||
|
not_null<DocumentData*> document) {
|
||||||
|
const auto session = &show->session();
|
||||||
|
const auto emoji = StickerEmojiOrDefault(document);
|
||||||
|
const auto failToast = [=](QString err) {
|
||||||
|
show->showToast(err.isEmpty()
|
||||||
|
? tr::lng_attach_failed(tr::now)
|
||||||
|
: err);
|
||||||
|
};
|
||||||
|
EnumerateOwnedStickerSets(session, [&](not_null<Data::StickersSet*> set) {
|
||||||
|
const auto identifier = set->identifier();
|
||||||
|
const auto coverDocument = set->lookupThumbnailDocument();
|
||||||
|
auto thumbnail = coverDocument
|
||||||
|
? Ui::MakeDocumentThumbnail(
|
||||||
|
coverDocument,
|
||||||
|
Data::FileOriginStickerSet(set->id, set->accessHash))
|
||||||
|
: nullptr;
|
||||||
|
const auto targetSetId = set->id;
|
||||||
|
const auto handler = crl::guard(session, [=] {
|
||||||
|
const auto &map = session->data().stickers().sets();
|
||||||
|
const auto i = map.find(targetSetId);
|
||||||
|
if (i != map.end()
|
||||||
|
&& i->second->count >= kStickersInOwnedSetMax) {
|
||||||
|
show->showToast(tr::lng_stickers_set_is_full(tr::now));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto oldCount = (i != map.end())
|
||||||
|
? i->second->count
|
||||||
|
: 0;
|
||||||
|
AddExistingStickerToSet(
|
||||||
|
session,
|
||||||
|
identifier,
|
||||||
|
document,
|
||||||
|
emoji,
|
||||||
|
crl::guard(session, [=](MTPmessages_StickerSet) {
|
||||||
|
const auto &map = session->data().stickers().sets();
|
||||||
|
const auto i = map.find(targetSetId);
|
||||||
|
const auto newCount = (i != map.end())
|
||||||
|
? i->second->count
|
||||||
|
: oldCount;
|
||||||
|
show->showToast(newCount > oldCount
|
||||||
|
? tr::lng_stickers_create_added(tr::now)
|
||||||
|
: tr::lng_stickers_already_in_set(tr::now));
|
||||||
|
}),
|
||||||
|
crl::guard(session, failToast));
|
||||||
|
});
|
||||||
|
const auto rawAction = Ui::Menu::CreateAction(
|
||||||
|
menu.get(),
|
||||||
|
set->title,
|
||||||
|
handler);
|
||||||
|
auto item = base::make_unique_q<Menu::ActionWithThumbnail>(
|
||||||
|
menu->menu(),
|
||||||
|
menu->menu()->st(),
|
||||||
|
rawAction,
|
||||||
|
std::move(thumbnail),
|
||||||
|
st::menuIconStickerAdd.width());
|
||||||
|
menu->addAction(std::move(item));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddAddToStickerSetAction(
|
||||||
|
const Ui::Menu::MenuCallback &addAction,
|
||||||
|
std::shared_ptr<ChatHelpers::Show> show,
|
||||||
|
not_null<DocumentData*> document) {
|
||||||
|
const auto session = &show->session();
|
||||||
|
if (!HasOwnedStickerSets(session)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
addAction({
|
||||||
|
.text = tr::lng_stickers_add_to_set(tr::now),
|
||||||
|
.icon = &st::menuIconStickerAdd,
|
||||||
|
.fillSubmenu = [show, document](not_null<Ui::PopupMenu*> submenu) {
|
||||||
|
FillChooseStickerSetMenu(submenu, show, document);
|
||||||
|
},
|
||||||
|
.submenuSt = &st::popupMenuWithIcons,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void DeleteStickerSet(
|
void DeleteStickerSet(
|
||||||
not_null<Main::Session*> session,
|
not_null<Main::Session*> session,
|
||||||
const StickerSetIdentifier &set,
|
const StickerSetIdentifier &set,
|
||||||
|
|||||||
@@ -13,12 +13,25 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||||||
|
|
||||||
class DocumentData;
|
class DocumentData;
|
||||||
|
|
||||||
|
namespace ChatHelpers {
|
||||||
|
class Show;
|
||||||
|
} // namespace ChatHelpers
|
||||||
|
|
||||||
namespace Main {
|
namespace Main {
|
||||||
class Session;
|
class Session;
|
||||||
} // namespace Main
|
} // namespace Main
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class PopupMenu;
|
||||||
|
namespace Menu {
|
||||||
|
struct MenuCallback;
|
||||||
|
} // namespace Menu
|
||||||
|
} // namespace Ui
|
||||||
|
|
||||||
namespace Api {
|
namespace Api {
|
||||||
|
|
||||||
|
inline constexpr auto kStickersInOwnedSetMax = 120;
|
||||||
|
|
||||||
void AddExistingStickerToSet(
|
void AddExistingStickerToSet(
|
||||||
not_null<Main::Session*> session,
|
not_null<Main::Session*> session,
|
||||||
const StickerSetIdentifier &set,
|
const StickerSetIdentifier &set,
|
||||||
@@ -33,6 +46,21 @@ void DeleteStickerSet(
|
|||||||
Fn<void()> done,
|
Fn<void()> done,
|
||||||
Fn<void(QString)> fail);
|
Fn<void(QString)> fail);
|
||||||
|
|
||||||
|
[[nodiscard]] bool HasOwnedStickerSets(not_null<Main::Session*> session);
|
||||||
|
|
||||||
|
[[nodiscard]] QString StickerEmojiOrDefault(
|
||||||
|
not_null<DocumentData*> document);
|
||||||
|
|
||||||
|
void FillChooseStickerSetMenu(
|
||||||
|
not_null<Ui::PopupMenu*> menu,
|
||||||
|
std::shared_ptr<ChatHelpers::Show> show,
|
||||||
|
not_null<DocumentData*> document);
|
||||||
|
|
||||||
|
void AddAddToStickerSetAction(
|
||||||
|
const Ui::Menu::MenuCallback &addAction,
|
||||||
|
std::shared_ptr<ChatHelpers::Show> show,
|
||||||
|
not_null<DocumentData*> document);
|
||||||
|
|
||||||
class StickerUpload final : public base::has_weak_ptr {
|
class StickerUpload final : public base::has_weak_ptr {
|
||||||
public:
|
public:
|
||||||
StickerUpload(
|
StickerUpload(
|
||||||
|
|||||||
@@ -85,7 +85,6 @@ constexpr auto kMinRepaintDelay = crl::time(33);
|
|||||||
constexpr auto kMinAfterScrollDelay = crl::time(33);
|
constexpr auto kMinAfterScrollDelay = crl::time(33);
|
||||||
constexpr auto kGrayLockOpacity = 0.3;
|
constexpr auto kGrayLockOpacity = 0.3;
|
||||||
constexpr auto kStickerMoveDuration = crl::time(200);
|
constexpr auto kStickerMoveDuration = crl::time(200);
|
||||||
constexpr auto kOwnedSetStickersMax = 120;
|
|
||||||
|
|
||||||
using Data::StickersSet;
|
using Data::StickersSet;
|
||||||
using Data::StickersPack;
|
using Data::StickersPack;
|
||||||
@@ -1638,6 +1637,12 @@ void StickerSetBox::Inner::contextMenuEvent(QContextMenuEvent *e) {
|
|||||||
(isFaved
|
(isFaved
|
||||||
? &st::menuIconUnfave
|
? &st::menuIconUnfave
|
||||||
: &st::menuIconFave));
|
: &st::menuIconFave));
|
||||||
|
if (!amSetCreator()) {
|
||||||
|
Api::AddAddToStickerSetAction(
|
||||||
|
Ui::Menu::CreateAddActionCallback(_menu.get()),
|
||||||
|
_show,
|
||||||
|
document);
|
||||||
|
}
|
||||||
if (amSetCreator()) {
|
if (amSetCreator()) {
|
||||||
const auto addAction = Ui::Menu::CreateAddActionCallback(
|
const auto addAction = Ui::Menu::CreateAddActionCallback(
|
||||||
_menu.get());
|
_menu.get());
|
||||||
@@ -2367,7 +2372,7 @@ bool StickerSetBox::Inner::hasAddCell() const {
|
|||||||
&& _amSetCreator
|
&& _amSetCreator
|
||||||
&& (setType() == Data::StickersType::Stickers)
|
&& (setType() == Data::StickersType::Stickers)
|
||||||
&& !_pack.isEmpty()
|
&& !_pack.isEmpty()
|
||||||
&& (_pack.size() < kOwnedSetStickersMax);
|
&& (_pack.size() < Api::kStickersInOwnedSetMax);
|
||||||
}
|
}
|
||||||
|
|
||||||
int StickerSetBox::Inner::totalCellsCount() const {
|
int StickerSetBox::Inner::totalCellsCount() const {
|
||||||
@@ -2504,11 +2509,7 @@ void StickerSetBox::Inner::startAddExistingStickerFlow() {
|
|||||||
if (_pickerPanel) {
|
if (_pickerPanel) {
|
||||||
_pickerPanel->hideAnimated();
|
_pickerPanel->hideAnimated();
|
||||||
}
|
}
|
||||||
const auto sticker = document->sticker();
|
const auto emoji = Api::StickerEmojiOrDefault(document);
|
||||||
const auto fallback = QString::fromUtf8("\xF0\x9F\x99\x82");
|
|
||||||
const auto emoji = (sticker && !sticker->alt.isEmpty())
|
|
||||||
? sticker->alt
|
|
||||||
: fallback;
|
|
||||||
Api::AddExistingStickerToSet(
|
Api::AddExistingStickerToSet(
|
||||||
session,
|
session,
|
||||||
identifier,
|
identifier,
|
||||||
|
|||||||
@@ -94,6 +94,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||||||
#include "apiwrap.h"
|
#include "apiwrap.h"
|
||||||
#include "api/api_attached_stickers.h"
|
#include "api/api_attached_stickers.h"
|
||||||
#include "api/api_suggest_post.h"
|
#include "api/api_suggest_post.h"
|
||||||
|
#include "api/api_stickers_creator.h"
|
||||||
#include "api/api_toggling_media.h"
|
#include "api/api_toggling_media.h"
|
||||||
#include "api/api_who_reacted.h"
|
#include "api/api_who_reacted.h"
|
||||||
#include "api/api_views.h"
|
#include "api/api_views.h"
|
||||||
@@ -3184,6 +3185,11 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
|||||||
_menu->addAction(document->isStickerSetInstalled() ? tr::lng_context_pack_info(tr::now) : tr::lng_context_pack_add(tr::now), [=] {
|
_menu->addAction(document->isStickerSetInstalled() ? tr::lng_context_pack_info(tr::now) : tr::lng_context_pack_add(tr::now), [=] {
|
||||||
showStickerPackInfo(document);
|
showStickerPackInfo(document);
|
||||||
}, &st::menuIconStickers);
|
}, &st::menuIconStickers);
|
||||||
|
} else {
|
||||||
|
Api::AddAddToStickerSetAction(
|
||||||
|
Ui::Menu::CreateAddActionCallback(_menu),
|
||||||
|
_controller->uiShow(),
|
||||||
|
document);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
const auto isFaved = session->data().stickers().isFaved(document);
|
const auto isFaved = session->data().stickers().isFaved(document);
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||||||
#include "api/api_ringtones.h"
|
#include "api/api_ringtones.h"
|
||||||
#include "api/api_transcribes.h"
|
#include "api/api_transcribes.h"
|
||||||
#include "api/api_who_reacted.h"
|
#include "api/api_who_reacted.h"
|
||||||
|
#include "api/api_stickers_creator.h"
|
||||||
#include "api/api_toggling_media.h" // Api::ToggleFavedSticker
|
#include "api/api_toggling_media.h" // Api::ToggleFavedSticker
|
||||||
#include "base/qt/qt_key_modifiers.h"
|
#include "base/qt/qt_key_modifiers.h"
|
||||||
#include "base/unixtime.h"
|
#include "base/unixtime.h"
|
||||||
@@ -33,6 +34,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||||||
#include "info/profile/info_profile_widget.h"
|
#include "info/profile/info_profile_widget.h"
|
||||||
#include "ui/widgets/popup_menu.h"
|
#include "ui/widgets/popup_menu.h"
|
||||||
#include "ui/widgets/menu/menu_action.h"
|
#include "ui/widgets/menu/menu_action.h"
|
||||||
|
#include "ui/widgets/menu/menu_add_action_callback_factory.h"
|
||||||
#include "ui/widgets/menu/menu_common.h"
|
#include "ui/widgets/menu/menu_common.h"
|
||||||
#include "ui/widgets/menu/menu_multiline_action.h"
|
#include "ui/widgets/menu/menu_multiline_action.h"
|
||||||
#include "ui/widgets/menu/menu_separator.h"
|
#include "ui/widgets/menu/menu_separator.h"
|
||||||
@@ -290,6 +292,12 @@ void AddDocumentActions(
|
|||||||
[=] { ShowStickerPackInfo(document, list); },
|
[=] { ShowStickerPackInfo(document, list); },
|
||||||
&st::menuIconStickers);
|
&st::menuIconStickers);
|
||||||
}
|
}
|
||||||
|
if (document->sticker() && !document->sticker()->set) {
|
||||||
|
Api::AddAddToStickerSetAction(
|
||||||
|
Ui::Menu::CreateAddActionCallback(menu),
|
||||||
|
controller->uiShow(),
|
||||||
|
document);
|
||||||
|
}
|
||||||
if (document->sticker()) {
|
if (document->sticker()) {
|
||||||
const auto isFaved = document->owner().stickers().isFaved(document);
|
const auto isFaved = document->owner().stickers().isFaved(document);
|
||||||
menu->addAction(
|
menu->addAction(
|
||||||
|
|||||||
@@ -1121,6 +1121,16 @@ std::shared_ptr<DynamicImage> MakeDocumentThumbnail(
|
|||||||
false);
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<DynamicImage> MakeDocumentThumbnail(
|
||||||
|
not_null<DocumentData*> document,
|
||||||
|
Data::FileOrigin origin) {
|
||||||
|
return std::make_shared<VideoThumbnail>(
|
||||||
|
document,
|
||||||
|
origin,
|
||||||
|
false,
|
||||||
|
false);
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<DynamicImage> MakeDocumentThumbnailCenterCrop(
|
std::shared_ptr<DynamicImage> MakeDocumentThumbnailCenterCrop(
|
||||||
not_null<DocumentData*> document,
|
not_null<DocumentData*> document,
|
||||||
FullMsgId fullId) {
|
FullMsgId fullId) {
|
||||||
|
|||||||
@@ -51,6 +51,9 @@ class DynamicImage;
|
|||||||
[[nodiscard]] std::shared_ptr<DynamicImage> MakeDocumentThumbnail(
|
[[nodiscard]] std::shared_ptr<DynamicImage> MakeDocumentThumbnail(
|
||||||
not_null<DocumentData*> document,
|
not_null<DocumentData*> document,
|
||||||
FullMsgId fullId);
|
FullMsgId fullId);
|
||||||
|
[[nodiscard]] std::shared_ptr<DynamicImage> MakeDocumentThumbnail(
|
||||||
|
not_null<DocumentData*> document,
|
||||||
|
Data::FileOrigin origin);
|
||||||
[[nodiscard]] std::shared_ptr<DynamicImage> MakeDocumentThumbnailCenterCrop(
|
[[nodiscard]] std::shared_ptr<DynamicImage> MakeDocumentThumbnailCenterCrop(
|
||||||
not_null<DocumentData*> document,
|
not_null<DocumentData*> document,
|
||||||
FullMsgId fullId);
|
FullMsgId fullId);
|
||||||
|
|||||||
Reference in New Issue
Block a user