mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Load and show image previews in pinned bar.
This commit is contained in:
parent
9b4b15ee6d
commit
37fb94cbfb
9 changed files with 136 additions and 15 deletions
|
@ -1266,6 +1266,15 @@ Image *DocumentData::getReplyPreview(Data::FileOrigin origin) {
|
||||||
return _replyPreview->image(origin);
|
return _replyPreview->image(origin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DocumentData::replyPreviewLoaded() const {
|
||||||
|
if (!hasThumbnail()) {
|
||||||
|
return true;
|
||||||
|
} else if (!_replyPreview) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return _replyPreview->loaded();
|
||||||
|
}
|
||||||
|
|
||||||
StickerData *DocumentData::sticker() const {
|
StickerData *DocumentData::sticker() const {
|
||||||
return (type == StickerDocument)
|
return (type == StickerDocument)
|
||||||
? static_cast<StickerData*>(_additional.get())
|
? static_cast<StickerData*>(_additional.get())
|
||||||
|
|
|
@ -126,6 +126,7 @@ public:
|
||||||
[[nodiscard]] bool saveToCache() const;
|
[[nodiscard]] bool saveToCache() const;
|
||||||
|
|
||||||
[[nodiscard]] Image *getReplyPreview(Data::FileOrigin origin);
|
[[nodiscard]] Image *getReplyPreview(Data::FileOrigin origin);
|
||||||
|
[[nodiscard]] bool replyPreviewLoaded() const;
|
||||||
|
|
||||||
[[nodiscard]] StickerData *sticker() const;
|
[[nodiscard]] StickerData *sticker() const;
|
||||||
[[nodiscard]] Data::FileOrigin stickerSetOrigin() const;
|
[[nodiscard]] Data::FileOrigin stickerSetOrigin() const;
|
||||||
|
|
|
@ -209,6 +209,10 @@ Image *Media::replyPreview() const {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Media::replyPreviewLoaded() const {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool Media::allowsForward() const {
|
bool Media::allowsForward() const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -312,6 +316,10 @@ Image *MediaPhoto::replyPreview() const {
|
||||||
return _photo->getReplyPreview(parent()->fullId());
|
return _photo->getReplyPreview(parent()->fullId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MediaPhoto::replyPreviewLoaded() const {
|
||||||
|
return _photo->replyPreviewLoaded();
|
||||||
|
}
|
||||||
|
|
||||||
QString MediaPhoto::notificationText() const {
|
QString MediaPhoto::notificationText() const {
|
||||||
return WithCaptionNotificationText(
|
return WithCaptionNotificationText(
|
||||||
tr::lng_in_dlg_photo(tr::now),
|
tr::lng_in_dlg_photo(tr::now),
|
||||||
|
@ -476,6 +484,10 @@ Image *MediaFile::replyPreview() const {
|
||||||
return _document->getReplyPreview(parent()->fullId());
|
return _document->getReplyPreview(parent()->fullId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MediaFile::replyPreviewLoaded() const {
|
||||||
|
return _document->replyPreviewLoaded();
|
||||||
|
}
|
||||||
|
|
||||||
QString MediaFile::chatListText() const {
|
QString MediaFile::chatListText() const {
|
||||||
if (const auto sticker = _document->sticker()) {
|
if (const auto sticker = _document->sticker()) {
|
||||||
return Media::chatListText();
|
return Media::chatListText();
|
||||||
|
@ -987,6 +999,15 @@ Image *MediaWebPage::replyPreview() const {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MediaWebPage::replyPreviewLoaded() const {
|
||||||
|
if (const auto document = MediaWebPage::document()) {
|
||||||
|
return document->replyPreviewLoaded();
|
||||||
|
} else if (const auto photo = MediaWebPage::photo()) {
|
||||||
|
return photo->replyPreviewLoaded();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
QString MediaWebPage::chatListText() const {
|
QString MediaWebPage::chatListText() const {
|
||||||
return notificationText();
|
return notificationText();
|
||||||
}
|
}
|
||||||
|
@ -1051,6 +1072,15 @@ Image *MediaGame::replyPreview() const {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MediaGame::replyPreviewLoaded() const {
|
||||||
|
if (const auto document = _game->document) {
|
||||||
|
return document->replyPreviewLoaded();
|
||||||
|
} else if (const auto photo = _game->photo) {
|
||||||
|
return photo->replyPreviewLoaded();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
QString MediaGame::notificationText() const {
|
QString MediaGame::notificationText() const {
|
||||||
// Add a game controller emoji before game title.
|
// Add a game controller emoji before game title.
|
||||||
auto result = QString();
|
auto result = QString();
|
||||||
|
@ -1153,6 +1183,13 @@ Image *MediaInvoice::replyPreview() const {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MediaInvoice::replyPreviewLoaded() const {
|
||||||
|
if (const auto photo = _invoice.photo) {
|
||||||
|
return photo->replyPreviewLoaded();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
QString MediaInvoice::notificationText() const {
|
QString MediaInvoice::notificationText() const {
|
||||||
return _invoice.title;
|
return _invoice.title;
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,6 +88,7 @@ public:
|
||||||
virtual bool canBeGrouped() const;
|
virtual bool canBeGrouped() const;
|
||||||
virtual bool hasReplyPreview() const;
|
virtual bool hasReplyPreview() const;
|
||||||
virtual Image *replyPreview() const;
|
virtual Image *replyPreview() const;
|
||||||
|
virtual bool replyPreviewLoaded() const;
|
||||||
// Returns text with link-start and link-end commands for service-color highlighting.
|
// Returns text with link-start and link-end commands for service-color highlighting.
|
||||||
// Example: "[link1-start]You:[link1-end] [link1-start]Photo,[link1-end] caption text"
|
// Example: "[link1-start]You:[link1-end] [link1-start]Photo,[link1-end] caption text"
|
||||||
virtual QString chatListText() const;
|
virtual QString chatListText() const;
|
||||||
|
@ -143,6 +144,7 @@ public:
|
||||||
bool canBeGrouped() const override;
|
bool canBeGrouped() const override;
|
||||||
bool hasReplyPreview() const override;
|
bool hasReplyPreview() const override;
|
||||||
Image *replyPreview() const override;
|
Image *replyPreview() const override;
|
||||||
|
bool replyPreviewLoaded() const override;
|
||||||
QString chatListText() const override;
|
QString chatListText() const override;
|
||||||
QString notificationText() const override;
|
QString notificationText() const override;
|
||||||
QString pinnedTextSubstring() const override;
|
QString pinnedTextSubstring() const override;
|
||||||
|
@ -180,6 +182,7 @@ public:
|
||||||
bool canBeGrouped() const override;
|
bool canBeGrouped() const override;
|
||||||
bool hasReplyPreview() const override;
|
bool hasReplyPreview() const override;
|
||||||
Image *replyPreview() const override;
|
Image *replyPreview() const override;
|
||||||
|
bool replyPreviewLoaded() const override;
|
||||||
QString chatListText() const override;
|
QString chatListText() const override;
|
||||||
QString notificationText() const override;
|
QString notificationText() const override;
|
||||||
QString pinnedTextSubstring() const override;
|
QString pinnedTextSubstring() const override;
|
||||||
|
@ -311,6 +314,7 @@ public:
|
||||||
|
|
||||||
bool hasReplyPreview() const override;
|
bool hasReplyPreview() const override;
|
||||||
Image *replyPreview() const override;
|
Image *replyPreview() const override;
|
||||||
|
bool replyPreviewLoaded() const override;
|
||||||
QString chatListText() const override;
|
QString chatListText() const override;
|
||||||
QString notificationText() const override;
|
QString notificationText() const override;
|
||||||
QString pinnedTextSubstring() const override;
|
QString pinnedTextSubstring() const override;
|
||||||
|
@ -341,6 +345,7 @@ public:
|
||||||
|
|
||||||
bool hasReplyPreview() const override;
|
bool hasReplyPreview() const override;
|
||||||
Image *replyPreview() const override;
|
Image *replyPreview() const override;
|
||||||
|
bool replyPreviewLoaded() const override;
|
||||||
QString notificationText() const override;
|
QString notificationText() const override;
|
||||||
QString pinnedTextSubstring() const override;
|
QString pinnedTextSubstring() const override;
|
||||||
TextForMimeData clipboardText() const override;
|
TextForMimeData clipboardText() const override;
|
||||||
|
@ -377,6 +382,7 @@ public:
|
||||||
|
|
||||||
bool hasReplyPreview() const override;
|
bool hasReplyPreview() const override;
|
||||||
Image *replyPreview() const override;
|
Image *replyPreview() const override;
|
||||||
|
bool replyPreviewLoaded() const override;
|
||||||
QString notificationText() const override;
|
QString notificationText() const override;
|
||||||
QString pinnedTextSubstring() const override;
|
QString pinnedTextSubstring() const override;
|
||||||
TextForMimeData clipboardText() const override;
|
TextForMimeData clipboardText() const override;
|
||||||
|
|
|
@ -205,6 +205,13 @@ Image *PhotoData::getReplyPreview(Data::FileOrigin origin) {
|
||||||
return _replyPreview->image(origin);
|
return _replyPreview->image(origin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PhotoData::replyPreviewLoaded() const {
|
||||||
|
if (!_replyPreview) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return _replyPreview->loaded();
|
||||||
|
}
|
||||||
|
|
||||||
void PhotoData::setRemoteLocation(
|
void PhotoData::setRemoteLocation(
|
||||||
int32 dc,
|
int32 dc,
|
||||||
uint64 access,
|
uint64 access,
|
||||||
|
|
|
@ -65,6 +65,7 @@ public:
|
||||||
[[nodiscard]] bool waitingForAlbum() const;
|
[[nodiscard]] bool waitingForAlbum() const;
|
||||||
|
|
||||||
[[nodiscard]] Image *getReplyPreview(Data::FileOrigin origin);
|
[[nodiscard]] Image *getReplyPreview(Data::FileOrigin origin);
|
||||||
|
[[nodiscard]] bool replyPreviewLoaded() const;
|
||||||
|
|
||||||
void setRemoteLocation(
|
void setRemoteLocation(
|
||||||
int32 dc,
|
int32 dc,
|
||||||
|
|
|
@ -107,4 +107,8 @@ Image *ReplyPreview::image(Data::FileOrigin origin) {
|
||||||
return _image.get();
|
return _image.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ReplyPreview::loaded() const {
|
||||||
|
return _checked;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Data
|
} // namespace Data
|
||||||
|
|
|
@ -24,6 +24,7 @@ public:
|
||||||
~ReplyPreview();
|
~ReplyPreview();
|
||||||
|
|
||||||
[[nodiscard]] Image *image(Data::FileOrigin origin);
|
[[nodiscard]] Image *image(Data::FileOrigin origin);
|
||||||
|
[[nodiscard]] bool loaded() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void prepare(not_null<Image*> image, Images::Options options);
|
void prepare(not_null<Image*> image, Images::Options options);
|
||||||
|
|
|
@ -23,29 +23,84 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
namespace HistoryView {
|
namespace HistoryView {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
[[nodiscard]] Ui::MessageBarContent ContentWithoutPreview(
|
||||||
|
not_null<HistoryItem*> item,
|
||||||
|
PinnedIdType type) {
|
||||||
|
const auto media = item->media();
|
||||||
|
const auto poll = media ? media->poll() : nullptr;
|
||||||
|
return Ui::MessageBarContent{
|
||||||
|
.id = item->id,
|
||||||
|
.title = ((type == PinnedIdType::First)
|
||||||
|
? tr::lng_pinned_previous(tr::now) // #TODO pinned first?
|
||||||
|
: (type == PinnedIdType::Middle)
|
||||||
|
? tr::lng_pinned_previous(tr::now)
|
||||||
|
: !poll
|
||||||
|
? tr::lng_pinned_message(tr::now)
|
||||||
|
: poll->quiz()
|
||||||
|
? tr::lng_pinned_quiz(tr::now)
|
||||||
|
: tr::lng_pinned_poll(tr::now)),
|
||||||
|
.text = item->inReplyText(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] Ui::MessageBarContent ContentWithPreview(
|
||||||
|
not_null<HistoryItem*> item,
|
||||||
|
PinnedIdType type,
|
||||||
|
Image *preview) {
|
||||||
|
auto result = ContentWithoutPreview(item, type);
|
||||||
|
if (!preview) {
|
||||||
|
static const auto kEmpty = [&] {
|
||||||
|
const auto size = st::historyReplyHeight * cIntRetinaFactor();
|
||||||
|
auto result = QImage(
|
||||||
|
QSize(size, size),
|
||||||
|
QImage::Format_ARGB32_Premultiplied);
|
||||||
|
result.fill(Qt::transparent);
|
||||||
|
result.setDevicePixelRatio(cRetinaFactor());
|
||||||
|
return result;
|
||||||
|
}();
|
||||||
|
result.preview = kEmpty;
|
||||||
|
} else {
|
||||||
|
result.preview = preview->original();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] rpl::producer<Ui::MessageBarContent> ContentByItem(
|
[[nodiscard]] rpl::producer<Ui::MessageBarContent> ContentByItem(
|
||||||
not_null<HistoryItem*> item,
|
not_null<HistoryItem*> item,
|
||||||
PinnedIdType type) {
|
PinnedIdType type) {
|
||||||
return item->history()->session().changes().messageFlagsValue(
|
return item->history()->session().changes().messageFlagsValue(
|
||||||
item,
|
item,
|
||||||
Data::MessageUpdate::Flag::Edited
|
Data::MessageUpdate::Flag::Edited
|
||||||
) | rpl::map([=] {
|
) | rpl::map([=]() -> rpl::producer<Ui::MessageBarContent> {
|
||||||
const auto media = item->media();
|
const auto media = item->media();
|
||||||
const auto poll = media ? media->poll() : nullptr;
|
if (!media || !media->hasReplyPreview()) {
|
||||||
return Ui::MessageBarContent{
|
return rpl::single(ContentWithoutPreview(item, type));
|
||||||
.id = item->id,
|
}
|
||||||
.title = ((type == PinnedIdType::First)
|
constexpr auto kFullLoaded = 2;
|
||||||
? tr::lng_pinned_previous(tr::now) // #TODO pinned first?
|
constexpr auto kSomeLoaded = 1;
|
||||||
: (type == PinnedIdType::Middle)
|
constexpr auto kNotLoaded = 0;
|
||||||
? tr::lng_pinned_previous(tr::now)
|
const auto loadedLevel = [=] {
|
||||||
: !poll
|
const auto preview = media->replyPreview();
|
||||||
? tr::lng_pinned_message(tr::now)
|
return media->replyPreviewLoaded()
|
||||||
: poll->quiz()
|
? kFullLoaded
|
||||||
? tr::lng_pinned_quiz(tr::now)
|
: preview
|
||||||
: tr::lng_pinned_poll(tr::now)),
|
? kSomeLoaded
|
||||||
.text = item->inReplyText(),
|
: kNotLoaded;
|
||||||
};
|
};
|
||||||
});
|
return rpl::single(
|
||||||
|
loadedLevel()
|
||||||
|
) | rpl::then(
|
||||||
|
item->history()->session().downloaderTaskFinished(
|
||||||
|
) | rpl::map(loadedLevel)
|
||||||
|
) | rpl::distinct_until_changed(
|
||||||
|
) | rpl::take_while([=](int loadLevel) {
|
||||||
|
return loadLevel < kFullLoaded;
|
||||||
|
}) | rpl::then(
|
||||||
|
rpl::single(kFullLoaded)
|
||||||
|
) | rpl::map([=] {
|
||||||
|
return ContentWithPreview(item, type, media->replyPreview());
|
||||||
|
});
|
||||||
|
}) | rpl::flatten_latest();
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] rpl::producer<Ui::MessageBarContent> ContentByItemId(
|
[[nodiscard]] rpl::producer<Ui::MessageBarContent> ContentByItemId(
|
||||||
|
|
Loading…
Add table
Reference in a new issue