mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Animate video userpics in chat history.
This commit is contained in:
parent
201edb2e69
commit
73bacfc650
9 changed files with 129 additions and 45 deletions
|
@ -401,6 +401,8 @@ void InnerWidget::paintEvent(QPaintEvent *e) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto activeEntry = _controller->activeChatEntryCurrent();
|
const auto activeEntry = _controller->activeChatEntryCurrent();
|
||||||
|
const auto videoPaused = _controller->isGifPausedAtLeastFor(
|
||||||
|
Window::GifPauseReason::Any);
|
||||||
auto fullWidth = width();
|
auto fullWidth = width();
|
||||||
auto dialogsClip = r;
|
auto dialogsClip = r;
|
||||||
auto ms = crl::now();
|
auto ms = crl::now();
|
||||||
|
@ -449,7 +451,8 @@ void InnerWidget::paintEvent(QPaintEvent *e) {
|
||||||
fullWidth,
|
fullWidth,
|
||||||
isActive,
|
isActive,
|
||||||
isSelected,
|
isSelected,
|
||||||
ms);
|
ms,
|
||||||
|
videoPaused);
|
||||||
if (xadd || yadd) {
|
if (xadd || yadd) {
|
||||||
p.translate(-xadd, -yadd);
|
p.translate(-xadd, -yadd);
|
||||||
}
|
}
|
||||||
|
@ -568,7 +571,8 @@ void InnerWidget::paintEvent(QPaintEvent *e) {
|
||||||
fullWidth,
|
fullWidth,
|
||||||
active,
|
active,
|
||||||
selected,
|
selected,
|
||||||
ms);
|
ms,
|
||||||
|
videoPaused);
|
||||||
p.translate(0, st::dialogsRowHeight);
|
p.translate(0, st::dialogsRowHeight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -686,13 +690,13 @@ Ui::VideoUserpic *InnerWidget::validateVideoUserpic(
|
||||||
if (i != end(_videoUserpics)) {
|
if (i != end(_videoUserpics)) {
|
||||||
return i->second.get();
|
return i->second.get();
|
||||||
}
|
}
|
||||||
const auto update = [=] {
|
const auto repaint = [=] {
|
||||||
updateDialogRow({ history, FullMsgId() });
|
updateDialogRow({ history, FullMsgId() });
|
||||||
updateSearchResult(history->peer);
|
updateSearchResult(history->peer);
|
||||||
};
|
};
|
||||||
return _videoUserpics.emplace(peer, std::make_unique<Ui::VideoUserpic>(
|
return _videoUserpics.emplace(peer, std::make_unique<Ui::VideoUserpic>(
|
||||||
peer,
|
peer,
|
||||||
update
|
repaint
|
||||||
)).first->second.get();
|
)).first->second.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -80,22 +80,6 @@ namespace {
|
||||||
: accumulated;
|
: accumulated;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PaintUserpic(
|
|
||||||
Painter &p,
|
|
||||||
not_null<PeerData*> peer,
|
|
||||||
Ui::VideoUserpic *videoUserpic,
|
|
||||||
std::shared_ptr<Data::CloudImageView> &view,
|
|
||||||
int x,
|
|
||||||
int y,
|
|
||||||
int outerWidth,
|
|
||||||
int size) {
|
|
||||||
if (videoUserpic) {
|
|
||||||
videoUserpic->paintLeft(p, view, x, y, outerWidth, size);
|
|
||||||
} else {
|
|
||||||
peer->paintUserpicLeft(p, view, x, y, outerWidth, size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
BasicRow::BasicRow() = default;
|
BasicRow::BasicRow() = default;
|
||||||
|
@ -142,7 +126,8 @@ void BasicRow::paintUserpic(
|
||||||
History *historyForCornerBadge,
|
History *historyForCornerBadge,
|
||||||
crl::time now,
|
crl::time now,
|
||||||
bool active,
|
bool active,
|
||||||
int fullWidth) const {
|
int fullWidth,
|
||||||
|
bool paused) const {
|
||||||
PaintUserpic(
|
PaintUserpic(
|
||||||
p,
|
p,
|
||||||
peer,
|
peer,
|
||||||
|
@ -151,7 +136,8 @@ void BasicRow::paintUserpic(
|
||||||
st::dialogsPadding.x(),
|
st::dialogsPadding.x(),
|
||||||
st::dialogsPadding.y(),
|
st::dialogsPadding.y(),
|
||||||
fullWidth,
|
fullWidth,
|
||||||
st::dialogsPhotoSize);
|
st::dialogsPhotoSize,
|
||||||
|
paused);
|
||||||
}
|
}
|
||||||
|
|
||||||
Row::Row(Key key, int pos) : _id(key), _pos(pos) {
|
Row::Row(Key key, int pos) : _id(key), _pos(pos) {
|
||||||
|
@ -232,7 +218,8 @@ void Row::PaintCornerBadgeFrame(
|
||||||
not_null<CornerBadgeUserpic*> data,
|
not_null<CornerBadgeUserpic*> data,
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
Ui::VideoUserpic *videoUserpic,
|
Ui::VideoUserpic *videoUserpic,
|
||||||
std::shared_ptr<Data::CloudImageView> &view) {
|
std::shared_ptr<Data::CloudImageView> &view,
|
||||||
|
bool paused) {
|
||||||
data->frame.fill(Qt::transparent);
|
data->frame.fill(Qt::transparent);
|
||||||
|
|
||||||
Painter q(&data->frame);
|
Painter q(&data->frame);
|
||||||
|
@ -244,7 +231,8 @@ void Row::PaintCornerBadgeFrame(
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
data->frame.width() / data->frame.devicePixelRatio(),
|
data->frame.width() / data->frame.devicePixelRatio(),
|
||||||
st::dialogsPhotoSize);
|
st::dialogsPhotoSize,
|
||||||
|
paused);
|
||||||
|
|
||||||
PainterHighQualityEnabler hq(q);
|
PainterHighQualityEnabler hq(q);
|
||||||
q.setCompositionMode(QPainter::CompositionMode_Source);
|
q.setCompositionMode(QPainter::CompositionMode_Source);
|
||||||
|
@ -279,7 +267,8 @@ void Row::paintUserpic(
|
||||||
History *historyForCornerBadge,
|
History *historyForCornerBadge,
|
||||||
crl::time now,
|
crl::time now,
|
||||||
bool active,
|
bool active,
|
||||||
int fullWidth) const {
|
int fullWidth,
|
||||||
|
bool paused) const {
|
||||||
updateCornerBadgeShown(peer);
|
updateCornerBadgeShown(peer);
|
||||||
|
|
||||||
const auto shown = _cornerBadgeUserpic
|
const auto shown = _cornerBadgeUserpic
|
||||||
|
@ -293,7 +282,8 @@ void Row::paintUserpic(
|
||||||
historyForCornerBadge,
|
historyForCornerBadge,
|
||||||
now,
|
now,
|
||||||
active,
|
active,
|
||||||
fullWidth);
|
fullWidth,
|
||||||
|
paused);
|
||||||
if (!historyForCornerBadge || !_cornerBadgeShown) {
|
if (!historyForCornerBadge || !_cornerBadgeShown) {
|
||||||
_cornerBadgeUserpic = nullptr;
|
_cornerBadgeUserpic = nullptr;
|
||||||
}
|
}
|
||||||
|
@ -322,7 +312,8 @@ void Row::paintUserpic(
|
||||||
_cornerBadgeUserpic.get(),
|
_cornerBadgeUserpic.get(),
|
||||||
peer,
|
peer,
|
||||||
videoUserpic,
|
videoUserpic,
|
||||||
userpicView());
|
userpicView(),
|
||||||
|
paused);
|
||||||
}
|
}
|
||||||
p.drawImage(st::dialogsPadding, _cornerBadgeUserpic->frame);
|
p.drawImage(st::dialogsPadding, _cornerBadgeUserpic->frame);
|
||||||
if (historyForCornerBadge->peer->isUser()) {
|
if (historyForCornerBadge->peer->isUser()) {
|
||||||
|
|
|
@ -45,7 +45,8 @@ public:
|
||||||
History *historyForCornerBadge,
|
History *historyForCornerBadge,
|
||||||
crl::time now,
|
crl::time now,
|
||||||
bool active,
|
bool active,
|
||||||
int fullWidth) const;
|
int fullWidth,
|
||||||
|
bool paused) const;
|
||||||
|
|
||||||
void addRipple(QPoint origin, QSize size, Fn<void()> updateCallback);
|
void addRipple(QPoint origin, QSize size, Fn<void()> updateCallback);
|
||||||
void stopLastRipple();
|
void stopLastRipple();
|
||||||
|
@ -84,7 +85,8 @@ public:
|
||||||
History *historyForCornerBadge,
|
History *historyForCornerBadge,
|
||||||
crl::time now,
|
crl::time now,
|
||||||
bool active,
|
bool active,
|
||||||
int fullWidth) const final override;
|
int fullWidth,
|
||||||
|
bool paused) const final override;
|
||||||
|
|
||||||
[[nodiscard]] Key key() const {
|
[[nodiscard]] Key key() const {
|
||||||
return _id;
|
return _id;
|
||||||
|
@ -131,7 +133,8 @@ private:
|
||||||
not_null<CornerBadgeUserpic*> data,
|
not_null<CornerBadgeUserpic*> data,
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
Ui::VideoUserpic *videoUserpic,
|
Ui::VideoUserpic *videoUserpic,
|
||||||
std::shared_ptr<Data::CloudImageView> &view);
|
std::shared_ptr<Data::CloudImageView> &view,
|
||||||
|
bool paused);
|
||||||
|
|
||||||
Key _id;
|
Key _id;
|
||||||
int _pos = 0;
|
int _pos = 0;
|
||||||
|
|
|
@ -302,6 +302,7 @@ enum class Flag {
|
||||||
SavedMessages = 0x08,
|
SavedMessages = 0x08,
|
||||||
RepliesMessages = 0x10,
|
RepliesMessages = 0x10,
|
||||||
AllowUserOnline = 0x20,
|
AllowUserOnline = 0x20,
|
||||||
|
VideoPaused = 0x40,
|
||||||
};
|
};
|
||||||
inline constexpr bool is_flag_type(Flag) { return true; }
|
inline constexpr bool is_flag_type(Flag) { return true; }
|
||||||
|
|
||||||
|
@ -366,7 +367,8 @@ void paintRow(
|
||||||
(flags & Flag::AllowUserOnline) ? history : nullptr,
|
(flags & Flag::AllowUserOnline) ? history : nullptr,
|
||||||
ms,
|
ms,
|
||||||
active,
|
active,
|
||||||
fullWidth);
|
fullWidth,
|
||||||
|
(flags & Flag::VideoPaused));
|
||||||
} else if (hiddenSenderInfo) {
|
} else if (hiddenSenderInfo) {
|
||||||
hiddenSenderInfo->emptyUserpic.paint(
|
hiddenSenderInfo->emptyUserpic.paint(
|
||||||
p,
|
p,
|
||||||
|
@ -798,7 +800,8 @@ void RowPainter::paint(
|
||||||
int fullWidth,
|
int fullWidth,
|
||||||
bool active,
|
bool active,
|
||||||
bool selected,
|
bool selected,
|
||||||
crl::time ms) {
|
crl::time ms,
|
||||||
|
bool paused) {
|
||||||
const auto entry = row->entry();
|
const auto entry = row->entry();
|
||||||
const auto history = row->history();
|
const auto history = row->history();
|
||||||
const auto peer = history ? history->peer.get() : nullptr;
|
const auto peer = history ? history->peer.get() : nullptr;
|
||||||
|
@ -868,7 +871,8 @@ void RowPainter::paint(
|
||||||
| (selected ? Flag::Selected : Flag(0))
|
| (selected ? Flag::Selected : Flag(0))
|
||||||
| (allowUserOnline ? Flag::AllowUserOnline : Flag(0))
|
| (allowUserOnline ? Flag::AllowUserOnline : Flag(0))
|
||||||
| (peer && peer->isSelf() ? Flag::SavedMessages : Flag(0))
|
| (peer && peer->isSelf() ? Flag::SavedMessages : Flag(0))
|
||||||
| (peer && peer->isRepliesChat() ? Flag::RepliesMessages : Flag(0));
|
| (peer && peer->isRepliesChat() ? Flag::RepliesMessages : Flag(0))
|
||||||
|
| (paused ? Flag::VideoPaused : Flag(0));
|
||||||
const auto paintItemCallback = [&](int nameleft, int namewidth) {
|
const auto paintItemCallback = [&](int nameleft, int namewidth) {
|
||||||
const auto texttop = st::dialogsPadding.y()
|
const auto texttop = st::dialogsPadding.y()
|
||||||
+ st::msgNameFont->height
|
+ st::msgNameFont->height
|
||||||
|
|
|
@ -37,7 +37,8 @@ public:
|
||||||
int fullWidth,
|
int fullWidth,
|
||||||
bool active,
|
bool active,
|
||||||
bool selected,
|
bool selected,
|
||||||
crl::time ms);
|
crl::time ms,
|
||||||
|
bool paused);
|
||||||
static void paint(
|
static void paint(
|
||||||
Painter &p,
|
Painter &p,
|
||||||
not_null<const FakeRow*> row,
|
not_null<const FakeRow*> row,
|
||||||
|
|
|
@ -33,7 +33,8 @@ void VideoUserpic::paintLeft(
|
||||||
int x,
|
int x,
|
||||||
int y,
|
int y,
|
||||||
int w,
|
int w,
|
||||||
int size) {
|
int size,
|
||||||
|
bool paused) {
|
||||||
_lastSize = size;
|
_lastSize = size;
|
||||||
|
|
||||||
const auto photoId = _peer->userpicPhotoId();
|
const auto photoId = _peer->userpicPhotoId();
|
||||||
|
@ -76,11 +77,8 @@ void VideoUserpic::paintLeft(
|
||||||
if (_video && _video->ready()) {
|
if (_video && _video->ready()) {
|
||||||
startReady();
|
startReady();
|
||||||
|
|
||||||
const auto now = crl::now();
|
const auto now = paused ? crl::time(0) : crl::now();
|
||||||
p.drawPixmap(
|
p.drawPixmap(x, y, _video->current(request(size), now));
|
||||||
x,
|
|
||||||
y,
|
|
||||||
_video->current(request(size), now));
|
|
||||||
} else {
|
} else {
|
||||||
_peer->paintUserpicLeft(p, view, x, y, w, size);
|
_peer->paintUserpicLeft(p, view, x, y, w, size);
|
||||||
}
|
}
|
||||||
|
@ -122,4 +120,21 @@ void VideoUserpic::clipCallback(Media::Clip::Notification notification) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PaintUserpic(
|
||||||
|
Painter &p,
|
||||||
|
not_null<PeerData*> peer,
|
||||||
|
Ui::VideoUserpic *videoUserpic,
|
||||||
|
std::shared_ptr<Data::CloudImageView> &view,
|
||||||
|
int x,
|
||||||
|
int y,
|
||||||
|
int outerWidth,
|
||||||
|
int size,
|
||||||
|
bool paused) {
|
||||||
|
if (videoUserpic) {
|
||||||
|
videoUserpic->paintLeft(p, view, x, y, outerWidth, size, paused);
|
||||||
|
} else {
|
||||||
|
peer->paintUserpicLeft(p, view, x, y, outerWidth, size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Dialogs::Ui
|
} // namespace Dialogs::Ui
|
||||||
|
|
|
@ -33,7 +33,8 @@ public:
|
||||||
int x,
|
int x,
|
||||||
int y,
|
int y,
|
||||||
int w,
|
int w,
|
||||||
int size);
|
int size,
|
||||||
|
bool paused);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void clipCallback(Media::Clip::Notification notification);
|
void clipCallback(Media::Clip::Notification notification);
|
||||||
|
@ -51,4 +52,15 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void PaintUserpic(
|
||||||
|
Painter &p,
|
||||||
|
not_null<PeerData*> peer,
|
||||||
|
Ui::VideoUserpic *videoUserpic,
|
||||||
|
std::shared_ptr<Data::CloudImageView> &view,
|
||||||
|
int x,
|
||||||
|
int y,
|
||||||
|
int outerWidth,
|
||||||
|
int size,
|
||||||
|
bool paused);
|
||||||
|
|
||||||
} // namespace Dialogs::Ui
|
} // namespace Dialogs::Ui
|
||||||
|
|
|
@ -84,6 +84,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "data/data_changes.h"
|
#include "data/data_changes.h"
|
||||||
#include "data/stickers/data_stickers.h"
|
#include "data/stickers/data_stickers.h"
|
||||||
#include "data/data_sponsored_messages.h"
|
#include "data/data_sponsored_messages.h"
|
||||||
|
#include "dialogs/ui/dialogs_video_userpic.h"
|
||||||
#include "facades.h"
|
#include "facades.h"
|
||||||
#include "styles/style_chat.h"
|
#include "styles/style_chat.h"
|
||||||
#include "styles/style_window.h" // st::windowMinWidth
|
#include "styles/style_window.h" // st::windowMinWidth
|
||||||
|
@ -367,8 +368,7 @@ HistoryInner::HistoryInner(
|
||||||
setMouseTracking(true);
|
setMouseTracking(true);
|
||||||
_controller->gifPauseLevelChanged(
|
_controller->gifPauseLevelChanged(
|
||||||
) | rpl::start_with_next([=] {
|
) | rpl::start_with_next([=] {
|
||||||
if (!_controller->isGifPausedAtLeastFor(
|
if (!elementIsGifPaused()) {
|
||||||
Window::GifPauseReason::Any)) {
|
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
|
@ -1079,6 +1079,7 @@ void HistoryInner::paintEvent(QPaintEvent *e) {
|
||||||
p.translate(0, -top);
|
p.translate(0, -top);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto paused = elementIsGifPaused();
|
||||||
enumerateUserpics([&](not_null<Element*> view, int userpicTop) {
|
enumerateUserpics([&](not_null<Element*> view, int userpicTop) {
|
||||||
// stop the enumeration if the userpic is below the painted rect
|
// stop the enumeration if the userpic is below the painted rect
|
||||||
if (userpicTop >= clip.top() + clip.height()) {
|
if (userpicTop >= clip.top() + clip.height()) {
|
||||||
|
@ -1088,13 +1089,16 @@ void HistoryInner::paintEvent(QPaintEvent *e) {
|
||||||
// paint the userpic if it intersects the painted rect
|
// paint the userpic if it intersects the painted rect
|
||||||
if (userpicTop + st::msgPhotoSize > clip.top()) {
|
if (userpicTop + st::msgPhotoSize > clip.top()) {
|
||||||
if (const auto from = view->data()->displayFrom()) {
|
if (const auto from = view->data()->displayFrom()) {
|
||||||
from->paintUserpicLeft(
|
Dialogs::Ui::PaintUserpic(
|
||||||
p,
|
p,
|
||||||
|
from,
|
||||||
|
validateVideoUserpic(from),
|
||||||
_userpics[from],
|
_userpics[from],
|
||||||
st::historyPhotoLeft,
|
st::historyPhotoLeft,
|
||||||
userpicTop,
|
userpicTop,
|
||||||
width(),
|
width(),
|
||||||
st::msgPhotoSize);
|
st::msgPhotoSize,
|
||||||
|
paused);
|
||||||
} else if (const auto info = view->data()->hiddenSenderInfo()) {
|
} else if (const auto info = view->data()->hiddenSenderInfo()) {
|
||||||
if (info->customUserpic.empty()) {
|
if (info->customUserpic.empty()) {
|
||||||
info->emptyUserpic.paint(
|
info->emptyUserpic.paint(
|
||||||
|
@ -1200,6 +1204,46 @@ bool HistoryInner::eventHook(QEvent *e) {
|
||||||
return RpWidget::eventHook(e);
|
return RpWidget::eventHook(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HistoryInner::VideoUserpic *HistoryInner::validateVideoUserpic(
|
||||||
|
not_null<PeerData*> peer) {
|
||||||
|
if (!peer->isPremium()
|
||||||
|
|| peer->userpicPhotoUnknown()
|
||||||
|
|| !peer->userpicHasVideo()) {
|
||||||
|
_videoUserpics.remove(peer);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
const auto i = _videoUserpics.find(peer);
|
||||||
|
if (i != end(_videoUserpics)) {
|
||||||
|
return i->second.get();
|
||||||
|
}
|
||||||
|
const auto repaint = [=] {
|
||||||
|
enumerateUserpics([&](not_null<Element*> view, int userpicTop) {
|
||||||
|
// stop the enumeration if the userpic is below the painted rect
|
||||||
|
if (userpicTop >= _visibleAreaBottom) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// repaint the userpic if it intersects the painted rect
|
||||||
|
if (userpicTop + st::msgPhotoSize > _visibleAreaTop) {
|
||||||
|
if (const auto from = view->data()->displayFrom()) {
|
||||||
|
if (from == peer) {
|
||||||
|
rtlupdate(
|
||||||
|
st::historyPhotoLeft,
|
||||||
|
userpicTop,
|
||||||
|
st::msgPhotoSize,
|
||||||
|
st::msgPhotoSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
return _videoUserpics.emplace(peer, std::make_unique<VideoUserpic>(
|
||||||
|
peer,
|
||||||
|
repaint
|
||||||
|
)).first->second.get();
|
||||||
|
}
|
||||||
|
|
||||||
void HistoryInner::onTouchScrollTimer() {
|
void HistoryInner::onTouchScrollTimer() {
|
||||||
auto nowTime = crl::now();
|
auto nowTime = crl::now();
|
||||||
if (_touchScrollState == Ui::TouchScrollState::Acceleration && _touchWaitingAcceleration && (nowTime - _touchAccelerationTime) > 40) {
|
if (_touchScrollState == Ui::TouchScrollState::Acceleration && _touchWaitingAcceleration && (nowTime - _touchAccelerationTime) > 40) {
|
||||||
|
|
|
@ -49,6 +49,10 @@ struct ChatPaintContext;
|
||||||
class PathShiftGradient;
|
class PathShiftGradient;
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
|
||||||
|
namespace Dialogs::Ui {
|
||||||
|
class VideoUserpic;
|
||||||
|
} // namespace Dialogs::Ui
|
||||||
|
|
||||||
class HistoryInner;
|
class HistoryInner;
|
||||||
class HistoryMainElementDelegate;
|
class HistoryMainElementDelegate;
|
||||||
class HistoryMainElementDelegateMixin {
|
class HistoryMainElementDelegateMixin {
|
||||||
|
@ -209,6 +213,7 @@ private:
|
||||||
void onTouchScrollTimer();
|
void onTouchScrollTimer();
|
||||||
|
|
||||||
class BotAbout;
|
class BotAbout;
|
||||||
|
using VideoUserpic = Dialogs::Ui::VideoUserpic;
|
||||||
using SelectedItems = std::map<HistoryItem*, TextSelection, std::less<>>;
|
using SelectedItems = std::map<HistoryItem*, TextSelection, std::less<>>;
|
||||||
enum class MouseAction {
|
enum class MouseAction {
|
||||||
None,
|
None,
|
||||||
|
@ -387,6 +392,8 @@ private:
|
||||||
bool showCopyRestrictionForSelected();
|
bool showCopyRestrictionForSelected();
|
||||||
[[nodiscard]] bool hasSelectRestriction() const;
|
[[nodiscard]] bool hasSelectRestriction() const;
|
||||||
|
|
||||||
|
VideoUserpic *validateVideoUserpic(not_null<PeerData*> peer);
|
||||||
|
|
||||||
// Does any of the shown histories has this flag set.
|
// Does any of the shown histories has this flag set.
|
||||||
bool hasPendingResizedItems() const;
|
bool hasPendingResizedItems() const;
|
||||||
|
|
||||||
|
@ -434,6 +441,9 @@ private:
|
||||||
base::flat_map<
|
base::flat_map<
|
||||||
MsgId,
|
MsgId,
|
||||||
std::shared_ptr<Data::CloudImageView>> _sponsoredUserpics;
|
std::shared_ptr<Data::CloudImageView>> _sponsoredUserpics;
|
||||||
|
base::flat_map<
|
||||||
|
not_null<PeerData*>,
|
||||||
|
std::unique_ptr<VideoUserpic>> _videoUserpics;
|
||||||
|
|
||||||
std::unique_ptr<HistoryView::Reactions::Manager> _reactionsManager;
|
std::unique_ptr<HistoryView::Reactions::Manager> _reactionsManager;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue