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_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_about" = "Pick an emoji that corresponds to this sticker.";
|
||||
"lng_stickers_pick_existing_title" = "Choose Sticker";
|
||||
|
||||
@@ -10,13 +10,23 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "apiwrap.h"
|
||||
#include "base/random.h"
|
||||
#include "base/unixtime.h"
|
||||
#include "chat_helpers/compose/compose_show.h"
|
||||
#include "data/data_document.h"
|
||||
#include "data/data_file_origin.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/stickers/data_stickers.h"
|
||||
#include "data/stickers/data_stickers_set.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "main/main_session.h"
|
||||
#include "menu/menu_action_with_thumbnail.h"
|
||||
#include "storage/file_upload.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 {
|
||||
@@ -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
|
||||
|
||||
void AddExistingStickerToSet(
|
||||
@@ -105,6 +144,104 @@ void AddExistingStickerToSet(
|
||||
}).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(
|
||||
not_null<Main::Session*> session,
|
||||
const StickerSetIdentifier &set,
|
||||
|
||||
@@ -13,12 +13,25 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
|
||||
class DocumentData;
|
||||
|
||||
namespace ChatHelpers {
|
||||
class Show;
|
||||
} // namespace ChatHelpers
|
||||
|
||||
namespace Main {
|
||||
class Session;
|
||||
} // namespace Main
|
||||
|
||||
namespace Ui {
|
||||
class PopupMenu;
|
||||
namespace Menu {
|
||||
struct MenuCallback;
|
||||
} // namespace Menu
|
||||
} // namespace Ui
|
||||
|
||||
namespace Api {
|
||||
|
||||
inline constexpr auto kStickersInOwnedSetMax = 120;
|
||||
|
||||
void AddExistingStickerToSet(
|
||||
not_null<Main::Session*> session,
|
||||
const StickerSetIdentifier &set,
|
||||
@@ -33,6 +46,21 @@ void DeleteStickerSet(
|
||||
Fn<void()> done,
|
||||
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 {
|
||||
public:
|
||||
StickerUpload(
|
||||
|
||||
@@ -85,7 +85,6 @@ constexpr auto kMinRepaintDelay = crl::time(33);
|
||||
constexpr auto kMinAfterScrollDelay = crl::time(33);
|
||||
constexpr auto kGrayLockOpacity = 0.3;
|
||||
constexpr auto kStickerMoveDuration = crl::time(200);
|
||||
constexpr auto kOwnedSetStickersMax = 120;
|
||||
|
||||
using Data::StickersSet;
|
||||
using Data::StickersPack;
|
||||
@@ -1638,6 +1637,12 @@ void StickerSetBox::Inner::contextMenuEvent(QContextMenuEvent *e) {
|
||||
(isFaved
|
||||
? &st::menuIconUnfave
|
||||
: &st::menuIconFave));
|
||||
if (!amSetCreator()) {
|
||||
Api::AddAddToStickerSetAction(
|
||||
Ui::Menu::CreateAddActionCallback(_menu.get()),
|
||||
_show,
|
||||
document);
|
||||
}
|
||||
if (amSetCreator()) {
|
||||
const auto addAction = Ui::Menu::CreateAddActionCallback(
|
||||
_menu.get());
|
||||
@@ -2367,7 +2372,7 @@ bool StickerSetBox::Inner::hasAddCell() const {
|
||||
&& _amSetCreator
|
||||
&& (setType() == Data::StickersType::Stickers)
|
||||
&& !_pack.isEmpty()
|
||||
&& (_pack.size() < kOwnedSetStickersMax);
|
||||
&& (_pack.size() < Api::kStickersInOwnedSetMax);
|
||||
}
|
||||
|
||||
int StickerSetBox::Inner::totalCellsCount() const {
|
||||
@@ -2504,11 +2509,7 @@ void StickerSetBox::Inner::startAddExistingStickerFlow() {
|
||||
if (_pickerPanel) {
|
||||
_pickerPanel->hideAnimated();
|
||||
}
|
||||
const auto sticker = document->sticker();
|
||||
const auto fallback = QString::fromUtf8("\xF0\x9F\x99\x82");
|
||||
const auto emoji = (sticker && !sticker->alt.isEmpty())
|
||||
? sticker->alt
|
||||
: fallback;
|
||||
const auto emoji = Api::StickerEmojiOrDefault(document);
|
||||
Api::AddExistingStickerToSet(
|
||||
session,
|
||||
identifier,
|
||||
|
||||
@@ -94,6 +94,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "apiwrap.h"
|
||||
#include "api/api_attached_stickers.h"
|
||||
#include "api/api_suggest_post.h"
|
||||
#include "api/api_stickers_creator.h"
|
||||
#include "api/api_toggling_media.h"
|
||||
#include "api/api_who_reacted.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), [=] {
|
||||
showStickerPackInfo(document);
|
||||
}, &st::menuIconStickers);
|
||||
} else {
|
||||
Api::AddAddToStickerSetAction(
|
||||
Ui::Menu::CreateAddActionCallback(_menu),
|
||||
_controller->uiShow(),
|
||||
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_transcribes.h"
|
||||
#include "api/api_who_reacted.h"
|
||||
#include "api/api_stickers_creator.h"
|
||||
#include "api/api_toggling_media.h" // Api::ToggleFavedSticker
|
||||
#include "base/qt/qt_key_modifiers.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 "ui/widgets/popup_menu.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_multiline_action.h"
|
||||
#include "ui/widgets/menu/menu_separator.h"
|
||||
@@ -290,6 +292,12 @@ void AddDocumentActions(
|
||||
[=] { ShowStickerPackInfo(document, list); },
|
||||
&st::menuIconStickers);
|
||||
}
|
||||
if (document->sticker() && !document->sticker()->set) {
|
||||
Api::AddAddToStickerSetAction(
|
||||
Ui::Menu::CreateAddActionCallback(menu),
|
||||
controller->uiShow(),
|
||||
document);
|
||||
}
|
||||
if (document->sticker()) {
|
||||
const auto isFaved = document->owner().stickers().isFaved(document);
|
||||
menu->addAction(
|
||||
|
||||
@@ -1121,6 +1121,16 @@ std::shared_ptr<DynamicImage> MakeDocumentThumbnail(
|
||||
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(
|
||||
not_null<DocumentData*> document,
|
||||
FullMsgId fullId) {
|
||||
|
||||
@@ -51,6 +51,9 @@ class DynamicImage;
|
||||
[[nodiscard]] std::shared_ptr<DynamicImage> MakeDocumentThumbnail(
|
||||
not_null<DocumentData*> document,
|
||||
FullMsgId fullId);
|
||||
[[nodiscard]] std::shared_ptr<DynamicImage> MakeDocumentThumbnail(
|
||||
not_null<DocumentData*> document,
|
||||
Data::FileOrigin origin);
|
||||
[[nodiscard]] std::shared_ptr<DynamicImage> MakeDocumentThumbnailCenterCrop(
|
||||
not_null<DocumentData*> document,
|
||||
FullMsgId fullId);
|
||||
|
||||
Reference in New Issue
Block a user