Added display of stories to list of recent posts in statistics info.

This commit is contained in:
23rd 2023-11-22 06:24:38 +03:00 committed by John Preston
parent 25d0123b9f
commit 1fbcec1d24
5 changed files with 151 additions and 47 deletions

View file

@ -13,6 +13,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/event_filter.h"
#include "data/data_peer.h"
#include "data/data_session.h"
#include "data/data_stories.h"
#include "data/data_story.h"
#include "history/history_item.h"
#include "info/info_controller.h"
#include "info/info_memento.h"
@ -697,26 +699,39 @@ void InnerWidget::fillRecentPosts() {
const auto addMessage = [=](
not_null<Ui::VerticalLayout*> messageWrap,
not_null<HistoryItem*> item,
HistoryItem *maybeItem,
Data::Story *maybeStory,
const Data::StatisticsMessageInteractionInfo &info) {
const auto button = messageWrap->add(
object_ptr<Ui::SettingsButton>(
messageWrap,
rpl::never<QString>(),
st::statisticsRecentPostButton));
auto it = _state.recentPostPreviews.find(
{ .messageId = item->fullId() });
const auto fullRecentId = RecentPostId{
.messageId = maybeItem ? maybeItem->fullId() : FullMsgId(),
.storyId = maybeStory ? maybeStory->fullId() : FullStoryId(),
};
auto it = _state.recentPostPreviews.find(fullRecentId);
auto cachedPreview = (it != end(_state.recentPostPreviews))
? base::take(it->second)
: QImage();
const auto raw = Ui::CreateChild<MessagePreview>(
button,
item,
info.viewsCount,
info.forwardsCount,
std::move(cachedPreview));
const auto raw = maybeItem
? Ui::CreateChild<MessagePreview>(
button,
maybeItem,
info.viewsCount,
info.forwardsCount,
std::move(cachedPreview))
: Ui::CreateChild<MessagePreview>(
button,
maybeStory,
info.viewsCount,
info.forwardsCount,
std::move(cachedPreview));
AddContextMenu(button, _controller, item);
if (maybeItem) {
AddContextMenu(button, _controller, maybeItem);
}
_messagePreviews.push_back(raw);
raw->show();
@ -727,8 +742,11 @@ void InnerWidget::fillRecentPosts() {
- st::statisticsRecentPostButton.padding);
}
}, raw->lifetime());
button->setClickedCallback([=, fullId = item->fullId()] {
_showRequests.fire({ .messageStatistic = fullId });
button->setClickedCallback([=] {
_showRequests.fire({
.messageStatistic = fullRecentId.messageId,
.storyStatistic = fullRecentId.storyId,
});
});
Ui::AddSkip(messageWrap);
if (!wrap->toggled()) {
@ -765,18 +783,30 @@ void InnerWidget::fillRecentPosts() {
const auto &recent = stats.recentMessageInteractions[i];
const auto messageWrap = content->add(
object_ptr<Ui::VerticalLayout>(content));
const auto msgId = recent.messageId;
if (const auto item = _peer->owner().message(_peer, msgId)) {
addMessage(messageWrap, item, recent);
continue;
}
const auto callback = crl::guard(content, [=] {
if (const auto item = _peer->owner().message(_peer, msgId)) {
addMessage(messageWrap, item, recent);
content->resizeToWidth(content->width());
auto &data = _peer->owner();
if (recent.messageId) {
const auto fullId = FullMsgId(_peer->id, recent.messageId);
if (const auto item = data.message(fullId)) {
addMessage(messageWrap, item, nullptr, recent);
continue;
}
});
_peer->session().api().requestMessageData(_peer, msgId, callback);
const auto callback = crl::guard(content, [=] {
if (const auto item = _peer->owner().message(fullId)) {
addMessage(messageWrap, item, nullptr, recent);
content->resizeToWidth(content->width());
}
});
_peer->session().api().requestMessageData(
_peer,
fullId.msg,
callback);
} else if (recent.storyId) {
const auto fullId = FullStoryId{ _peer->id, recent.storyId };
if (const auto story = data.stories().lookup(fullId)) {
addMessage(messageWrap, nullptr, *story, recent);
continue;
}
}
}
container->resizeToWidth(container->width());
};

View file

@ -32,6 +32,7 @@ public:
PeerId info = PeerId(0);
FullMsgId history;
FullMsgId messageStatistic;
FullStoryId storyStatistic;
};
InnerWidget(

View file

@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "info/statistics/info_statistics_recent_message.h"
#include "base/unixtime.h"
#include "core/ui_integration.h"
#include "data/data_document.h"
#include "data/data_document_media.h"
@ -14,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_photo.h"
#include "data/data_photo_media.h"
#include "data/data_session.h"
#include "data/data_story.h"
#include "history/history.h"
#include "history/history_item.h"
#include "history/history_item_helpers.h"
@ -21,13 +23,16 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "info/statistics/info_statistics_common.h"
#include "lang/lang_keys.h"
#include "main/main_session.h"
#include "ui/effects/outline_segments.h" // UnreadStoryOutlineGradient
#include "ui/effects/ripple_animation.h"
#include "ui/effects/spoiler_mess.h"
#include "ui/painter.h"
#include "ui/power_saving.h"
#include "ui/rect.h"
#include "ui/text/format_values.h"
#include "ui/text/text_options.h"
#include "styles/style_boxes.h"
#include "styles/style_dialogs.h"
#include "styles/style_layers.h"
#include "styles/style_statistics.h"
@ -73,6 +78,7 @@ MessagePreview::MessagePreview(
int shares,
QImage cachedPreview)
: Ui::RpWidget(parent)
, _messageId(item->fullId())
, _date(
st::statisticsHeaderTitleTextStyle,
Ui::FormatDateTime(ItemDateTime(item)))
@ -103,26 +109,74 @@ MessagePreview::MessagePreview(
.session = &item->history()->session(),
.customEmojiRepaint = [=] { update(); },
});
if (item->media()->hasSpoiler()) {
_spoiler = std::make_unique<Ui::SpoilerAnimation>([=] { update(); });
}
if (_preview.isNull()) {
processPreview(item);
if (const auto media = item->media()) {
if (const auto photo = media->photo()) {
_photoMedia = photo->createMediaView();
_photoMedia->wanted(Data::PhotoSize::Large, item->fullId());
} else if (const auto document = media->document()) {
_documentMedia = document->createMediaView();
_documentMedia->thumbnailWanted(item->fullId());
}
}
processPreview();
}
}
void MessagePreview::processPreview(not_null<HistoryItem*> item) {
if (const auto media = item->media()) {
if (item->media()->hasSpoiler()) {
_spoiler = std::make_unique<Ui::SpoilerAnimation>([=] {
update();
});
}
if (const auto photo = media->photo()) {
MessagePreview::MessagePreview(
not_null<Ui::RpWidget*> parent,
not_null<Data::Story*> story,
int views,
int shares,
QImage cachedPreview)
: Ui::RpWidget(parent)
, _storyId(story->fullId())
, _date(
st::statisticsHeaderTitleTextStyle,
Ui::FormatDateTime(base::unixtime::parse(story->date())))
, _views(
st::defaultPeerListItem.nameStyle,
(views >= 0)
? tr::lng_stats_recent_messages_views(
tr::now,
lt_count_decimal,
views)
: QString())
, _shares(
st::statisticsHeaderTitleTextStyle,
(shares >= 0)
? tr::lng_stats_recent_messages_shares(
tr::now,
lt_count_decimal,
shares)
: QString())
, _viewsWidth(_views.maxWidth())
, _sharesWidth(_shares.maxWidth())
, _preview(std::move(cachedPreview)) {
_text.setMarkedText(
st::defaultPeerListItem.nameStyle,
{ tr::lng_in_dlg_story(tr::now) },
Ui::DialogTextOptions(),
Core::MarkedTextContext{
.session = &story->peer()->session(),
.customEmojiRepaint = [=] { update(); },
});
if (_preview.isNull()) {
if (const auto photo = story->photo()) {
_photoMedia = photo->createMediaView();
_photoMedia->wanted(Data::PhotoSize::Large, item->fullId());
} else if (const auto document = media->document()) {
_photoMedia->wanted(Data::PhotoSize::Large, story->fullId());
} else if (const auto document = story->document()) {
_documentMedia = document->createMediaView();
_documentMedia->thumbnailWanted(item->fullId());
_documentMedia->thumbnailWanted(story->fullId());
}
processPreview();
}
}
void MessagePreview::processPreview() {
const auto session = _photoMedia
? &_photoMedia->owner()->session()
: _documentMedia
@ -143,9 +197,8 @@ void MessagePreview::processPreview(not_null<HistoryItem*> item) {
return { true, _documentMedia->thumbnail() };
} else if (const auto large = _photoMedia->image(Size::Large)) {
return { true, large };
} else if (const auto thumbnail = _photoMedia->image(
Size::Thumbnail)) {
return { false, thumbnail };
} else if (const auto thumb = _photoMedia->image(Size::Thumbnail)) {
return { false, thumb };
} else if (const auto small = _photoMedia->image(Size::Small)) {
return { false, small };
} else {
@ -168,7 +221,7 @@ void MessagePreview::processPreview(not_null<HistoryItem*> item) {
}
_preview = PreparePreviewImage(
computed.image->original(),
ImageRoundRadius::Large,
_messageId ? ImageRoundRadius::Large : ImageRoundRadius::Ellipse,
!!_spoiler);
}, _lifetimeDownload);
}
@ -186,11 +239,11 @@ void MessagePreview::paintEvent(QPaintEvent *e) {
? st::peerListBoxItem.photoPosition.x()
: st::peerListBoxItem.namePosition.x();
if (left) {
p.drawImage(st::peerListBoxItem.photoPosition, _preview);
const auto rect = QRect(
st::peerListBoxItem.photoPosition,
Size(st::peerListBoxItem.photoSize));
p.drawImage(rect.topLeft(), _preview);
if (_spoiler) {
const auto rect = QRect(
st::peerListBoxItem.photoPosition,
Size(st::peerListBoxItem.photoSize));
const auto paused = On(PowerSaving::kChatSpoiler);
FillSpoilerRect(
p,
@ -201,6 +254,17 @@ void MessagePreview::paintEvent(QPaintEvent *e) {
_spoiler->index(crl::now(), paused)),
_cornerCache);
}
if (_storyId) {
auto hq = PainterHighQualityEnabler(p);
const auto line = st::dialogsStoriesFull.lineTwice / 2.;
auto gradient = Ui::UnreadStoryOutlineGradient();
gradient.setStart(rect.topRight());
gradient.setFinalStop(rect.bottomLeft());
p.setPen(QPen(gradient, line));
p.setBrush(Qt::NoBrush);
p.drawEllipse(rect + Margins(1.5 * line));
}
}
const auto topTextTop = st::peerListBoxItem.namePosition.y();
const auto bottomTextTop = st::peerListBoxItem.statusPosition.y();
@ -237,7 +301,8 @@ void MessagePreview::paintEvent(QPaintEvent *e) {
void MessagePreview::saveState(SavedState &state) const {
if (!_lifetimeDownload) {
state.recentPostPreviews[{ .messageId = _messageId }] = _preview;
const auto fullId = RecentPostId{ _messageId, _storyId };
state.recentPostPreviews[fullId] = _preview;
}
}

View file

@ -14,6 +14,7 @@ class HistoryItem;
namespace Data {
class DocumentMedia;
class PhotoMedia;
class Story;
} // namespace Data
namespace Ui {
@ -32,6 +33,12 @@ public:
int views,
int shares,
QImage cachedPreview);
MessagePreview(
not_null<Ui::RpWidget*> parent,
not_null<Data::Story*> story,
int views,
int shares,
QImage cachedPreview);
void saveState(SavedState &state) const;
@ -41,9 +48,10 @@ protected:
int resizeGetHeight(int newWidth) override;
private:
void processPreview(not_null<HistoryItem*> item);
void processPreview();
FullMsgId _messageId;
FullStoryId _storyId;
Ui::Text::String _text;
Ui::Text::String _date;
Ui::Text::String _views;

View file

@ -73,11 +73,11 @@ Widget::Widget(
request.history.msg);
} else if (request.info) {
controller->showPeerInfo(request.info);
} else if (request.messageStatistic) {
} else if (request.messageStatistic || request.storyStatistic) {
controller->showSection(Make(
controller->statisticsPeer(),
request.messageStatistic,
{}));
request.storyStatistic));
}
}, _inner->lifetime());
_inner->scrollToRequests(