tdesktop/Telegram/SourceFiles/chat_helpers/gifs_list_widget.h
2023-07-20 07:20:08 +04:00

226 lines
5.7 KiB
C++

/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include "chat_helpers/tabbed_selector.h"
#include "base/timer.h"
#include "inline_bots/inline_bot_layout_item.h"
#include "layout/layout_mosaic.h"
#include <QtCore/QTimer>
namespace style {
struct ComposeIcons;
} // namespace style
namespace Api {
struct SendOptions;
} // namespace Api
namespace InlineBots {
namespace Layout {
class ItemBase;
} // namespace Layout
class Result;
} // namespace InlineBots
namespace Ui {
class PopupMenu;
class RoundButton;
class TabbedSearch;
} // namespace Ui
namespace Window {
class SessionController;
} // namespace Window
namespace SendMenu {
enum class Type;
} // namespace SendMenu
namespace Data {
class StickersSet;
} // namespace Data
namespace ChatHelpers {
void AddGifAction(
Fn<void(QString, Fn<void()> &&, const style::icon*)> callback,
std::shared_ptr<Show> show,
not_null<DocumentData*> document,
const style::ComposeIcons *iconsOverride = nullptr);
class StickersListFooter;
struct StickerIcon;
struct GifSection;
struct GifsListDescriptor {
std::shared_ptr<Show> show;
Fn<bool()> paused;
const style::EmojiPan *st = nullptr;
};
class GifsListWidget final
: public TabbedSelector::Inner
, public InlineBots::Layout::Context {
public:
GifsListWidget(
QWidget *parent,
not_null<Window::SessionController*> controller,
PauseReason level);
GifsListWidget(QWidget *parent, GifsListDescriptor &&descriptor);
rpl::producer<FileChosen> fileChosen() const;
rpl::producer<PhotoChosen> photoChosen() const;
rpl::producer<InlineChosen> inlineResultChosen() const;
void refreshRecent() override;
void preloadImages() override;
void clearSelection() override;
object_ptr<TabbedSelector::InnerFooter> createFooter() override;
void inlineItemLayoutChanged(const InlineBots::Layout::ItemBase *layout) override;
void inlineItemRepaint(const InlineBots::Layout::ItemBase *layout) override;
bool inlineItemVisible(const InlineBots::Layout::ItemBase *layout) override;
Data::FileOrigin inlineItemFileOrigin() override;
void afterShown() override;
void beforeHiding() override;
void setInlineQueryPeer(PeerData *peer) {
_inlineQueryPeer = peer;
}
void searchForGifs(const QString &query);
void sendInlineRequest();
void cancelled();
rpl::producer<> cancelRequests() const;
base::unique_qptr<Ui::PopupMenu> fillContextMenu(
SendMenu::Type type) override;
~GifsListWidget();
protected:
void visibleTopBottomUpdated(
int visibleTop,
int visibleBottom) override;
void mousePressEvent(QMouseEvent *e) override;
void mouseReleaseEvent(QMouseEvent *e) override;
void mouseMoveEvent(QMouseEvent *e) override;
void paintEvent(QPaintEvent *e) override;
void leaveEventHook(QEvent *e) override;
void leaveToChildEvent(QEvent *e, QWidget *child) override;
void enterFromChildEvent(QEvent *e, QWidget *child) override;
TabbedSelector::InnerFooter *getFooter() const override;
void processHideFinished() override;
void processPanelHideFinished() override;
int countDesiredHeight(int newWidth) override;
private:
enum class Section {
Inlines,
Gifs,
};
using InlineResult = InlineBots::Result;
using InlineResults = std::vector<std::unique_ptr<InlineResult>>;
using LayoutItem = InlineBots::Layout::ItemBase;
struct InlineCacheEntry {
QString nextOffset;
InlineResults results;
};
void setupSearch();
void clearHeavyData();
void cancelGifsSearch();
void switchToSavedGifs();
void refreshSavedGifs();
int refreshInlineRows(const InlineCacheEntry *results, bool resultsDeleted);
void checkLoadMore();
int32 showInlineRows(bool newResults);
bool refreshInlineRows(int32 *added = 0);
void inlineResultsDone(const MTPmessages_BotResults &result);
void updateSelected();
void paintInlineItems(Painter &p, QRect clip);
void refreshIcons();
[[nodiscard]] std::vector<StickerIcon> fillIcons();
void updateInlineItems();
void repaintItems(crl::time now = 0);
void showPreview();
void clearInlineRows(bool resultsDeleted);
LayoutItem *layoutPrepareSavedGif(not_null<DocumentData*> document);
LayoutItem *layoutPrepareInlineResult(not_null<InlineResult*> result);
void deleteUnusedGifLayouts();
void deleteUnusedInlineLayouts();
int validateExistingInlineRows(const InlineResults &results);
void selectInlineResult(
int index,
Api::SendOptions options,
bool forceSend = false);
const std::shared_ptr<Show> _show;
std::unique_ptr<Ui::TabbedSearch> _search;
MTP::Sender _api;
Section _section = Section::Gifs;
crl::time _lastScrolledAt = 0;
crl::time _lastUpdatedAt = 0;
base::Timer _updateInlineItems;
bool _inlineWithThumb = false;
std::map<
not_null<DocumentData*>,
std::unique_ptr<LayoutItem>> _gifLayouts;
std::map<
not_null<InlineResult*>,
std::unique_ptr<LayoutItem>> _inlineLayouts;
StickersListFooter *_footer = nullptr;
std::vector<GifSection> _sections;
base::flat_map<uint64, std::unique_ptr<Data::StickersSet>> _fakeSets;
uint64 _chosenSetId = 0;
Mosaic::Layout::MosaicLayout<LayoutItem> _mosaic;
int _selected = -1;
int _pressed = -1;
QPoint _lastMousePos;
base::Timer _previewTimer;
bool _previewShown = false;
std::map<QString, std::unique_ptr<InlineCacheEntry>> _inlineCache;
QTimer _inlineRequestTimer;
UserData *_searchBot = nullptr;
mtpRequestId _searchBotRequestId = 0;
PeerData *_inlineQueryPeer = nullptr;
QString _inlineQuery, _inlineNextQuery, _inlineNextOffset;
mtpRequestId _inlineRequestId = 0;
rpl::event_stream<FileChosen> _fileChosen;
rpl::event_stream<PhotoChosen> _photoChosen;
rpl::event_stream<InlineChosen> _inlineResultChosen;
rpl::event_stream<> _cancelled;
};
} // namespace ChatHelpers