Fixed possible crash in sending animation when message view is lost.
This commit is contained in:
parent
d2d41f978d
commit
a61ad9e2a2
|
@ -50,7 +50,8 @@ private:
|
||||||
|
|
||||||
void createSurrounding();
|
void createSurrounding();
|
||||||
void createBubble();
|
void createBubble();
|
||||||
not_null<HistoryView::Element*> view() const;
|
HistoryView::Element *maybeView() const;
|
||||||
|
bool checkView(HistoryView::Element *currentView) const;
|
||||||
void drawContent(Painter &p, float64 progress) const;
|
void drawContent(Painter &p, float64 progress) const;
|
||||||
|
|
||||||
const not_null<Window::SessionController*> _controller;
|
const not_null<Window::SessionController*> _controller;
|
||||||
|
@ -83,7 +84,7 @@ Content::Content(
|
||||||
, _crop(fromInfo.crop)
|
, _crop(fromInfo.crop)
|
||||||
, _toInfo(std::move(to))
|
, _toInfo(std::move(to))
|
||||||
, _from(parent->mapFromGlobal(fromInfo.globalStartGeometry))
|
, _from(parent->mapFromGlobal(fromInfo.globalStartGeometry))
|
||||||
, _innerContentRect(view()->media()->contentRectForReactions())
|
, _innerContentRect(maybeView()->media()->contentRectForReactions())
|
||||||
, _minScale(float64(_from.height()) / _innerContentRect.height()) {
|
, _minScale(float64(_from.height()) / _innerContentRect.height()) {
|
||||||
Expects(_toInfo.view != nullptr);
|
Expects(_toInfo.view != nullptr);
|
||||||
Expects(_toInfo.paintContext != nullptr);
|
Expects(_toInfo.paintContext != nullptr);
|
||||||
|
@ -106,7 +107,7 @@ Content::Content(
|
||||||
|
|
||||||
resize(_innerContentRect.size());
|
resize(_innerContentRect.size());
|
||||||
|
|
||||||
const auto innerGeometry = view()->innerGeometry();
|
const auto innerGeometry = maybeView()->innerGeometry();
|
||||||
|
|
||||||
auto animationCallback = [=](float64 value) {
|
auto animationCallback = [=](float64 value) {
|
||||||
auto resultFrom = rect();
|
auto resultFrom = rect();
|
||||||
|
@ -123,7 +124,11 @@ Content::Content(
|
||||||
if ((value > kSurroundingProgress)
|
if ((value > kSurroundingProgress)
|
||||||
&& !_surrounding
|
&& !_surrounding
|
||||||
&& !_bubble.widget) {
|
&& !_bubble.widget) {
|
||||||
if (view()->hasBubble()) {
|
const auto currentView = maybeView();
|
||||||
|
if (!checkView(currentView)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (currentView->hasBubble()) {
|
||||||
createBubble();
|
createBubble();
|
||||||
} else {
|
} else {
|
||||||
createSurrounding();
|
createSurrounding();
|
||||||
|
@ -141,7 +146,10 @@ Content::Content(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value == 1.) {
|
if (value == 1.) {
|
||||||
const auto currentView = view();
|
const auto currentView = maybeView();
|
||||||
|
if (!checkView(currentView)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const auto controller = _controller;
|
const auto controller = _controller;
|
||||||
_destroyRequests.fire({});
|
_destroyRequests.fire({});
|
||||||
controller->session().data().requestViewRepaint(currentView);
|
controller->session().data().requestViewRepaint(currentView);
|
||||||
|
@ -155,10 +163,18 @@ Content::Content(
|
||||||
HistoryView::ListWidget::kItemRevealDuration);
|
HistoryView::ListWidget::kItemRevealDuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
not_null<HistoryView::Element*> Content::view() const {
|
HistoryView::Element *Content::maybeView() const {
|
||||||
return _toInfo.view();
|
return _toInfo.view();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Content::checkView(HistoryView::Element *currentView) const {
|
||||||
|
if (!currentView) {
|
||||||
|
_destroyRequests.fire({});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void Content::paintEvent(QPaintEvent *e) {
|
void Content::paintEvent(QPaintEvent *e) {
|
||||||
const auto progress = _animation.value(_animation.animating() ? 0. : 1.);
|
const auto progress = _animation.value(_animation.animating() ? 0. : 1.);
|
||||||
|
|
||||||
|
@ -211,7 +227,10 @@ void Content::drawContent(Painter &p, float64 progress) const {
|
||||||
(1 - progress) * OffsetMid(height(), _minScale));
|
(1 - progress) * OffsetMid(height(), _minScale));
|
||||||
p.scale(scale, scale);
|
p.scale(scale, scale);
|
||||||
|
|
||||||
const auto currentView = view();
|
const auto currentView = maybeView();
|
||||||
|
if (!checkView(currentView)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
auto context = _toInfo.paintContext();
|
auto context = _toInfo.paintContext();
|
||||||
context.skipDrawingParts = Context::SkipDrawingParts::Surrounding;
|
context.skipDrawingParts = Context::SkipDrawingParts::Surrounding;
|
||||||
|
@ -228,7 +247,10 @@ void Content::createSurrounding() {
|
||||||
_surrounding = base::make_unique_q<Ui::RpWidget>(parentWidget());
|
_surrounding = base::make_unique_q<Ui::RpWidget>(parentWidget());
|
||||||
_surrounding->setAttribute(Qt::WA_TransparentForMouseEvents);
|
_surrounding->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||||
|
|
||||||
const auto currentView = view();
|
const auto currentView = maybeView();
|
||||||
|
if (!checkView(currentView)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const auto surroundingSize = currentView->innerGeometry().size();
|
const auto surroundingSize = currentView->innerGeometry().size();
|
||||||
const auto offset = _innerContentRect.topLeft();
|
const auto offset = _innerContentRect.topLeft();
|
||||||
|
|
||||||
|
@ -259,7 +281,10 @@ void Content::createSurrounding() {
|
||||||
revProgress * OffsetMid(size.height() + offset.y(), _minScale));
|
revProgress * OffsetMid(size.height() + offset.y(), _minScale));
|
||||||
p.scale(scale, scale);
|
p.scale(scale, scale);
|
||||||
|
|
||||||
const auto currentView = view();
|
const auto currentView = maybeView();
|
||||||
|
if (!checkView(currentView)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
auto context = _toInfo.paintContext();
|
auto context = _toInfo.paintContext();
|
||||||
context.skipDrawingParts = Context::SkipDrawingParts::Content;
|
context.skipDrawingParts = Context::SkipDrawingParts::Content;
|
||||||
|
@ -273,7 +298,10 @@ void Content::createBubble() {
|
||||||
_bubble.widget = base::make_unique_q<Ui::RpWidget>(parentWidget());
|
_bubble.widget = base::make_unique_q<Ui::RpWidget>(parentWidget());
|
||||||
_bubble.widget->setAttribute(Qt::WA_TransparentForMouseEvents);
|
_bubble.widget->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||||
|
|
||||||
const auto currentView = view();
|
const auto currentView = maybeView();
|
||||||
|
if (!checkView(currentView)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const auto innerGeometry = currentView->innerGeometry();
|
const auto innerGeometry = currentView->innerGeometry();
|
||||||
|
|
||||||
const auto tailWidth = st::historyBubbleTailOutLeft.width();
|
const auto tailWidth = st::historyBubbleTailOutLeft.width();
|
||||||
|
@ -315,7 +343,10 @@ void Content::createBubble() {
|
||||||
revProgress * OffsetMid(height() + scaleOffset.y(), _minScale));
|
revProgress * OffsetMid(height() + scaleOffset.y(), _minScale));
|
||||||
p.scale(scale, scale);
|
p.scale(scale, scale);
|
||||||
|
|
||||||
const auto currentView = view();
|
const auto currentView = maybeView();
|
||||||
|
if (!checkView(currentView)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
auto context = _toInfo.paintContext();
|
auto context = _toInfo.paintContext();
|
||||||
context.skipDrawingParts = Context::SkipDrawingParts::Content;
|
context.skipDrawingParts = Context::SkipDrawingParts::Content;
|
||||||
|
|
|
@ -30,7 +30,7 @@ public:
|
||||||
|
|
||||||
struct SendingInfoTo {
|
struct SendingInfoTo {
|
||||||
rpl::producer<QPoint> globalEndTopLeft;
|
rpl::producer<QPoint> globalEndTopLeft;
|
||||||
Fn<not_null<HistoryView::Element*>()> view;
|
Fn<HistoryView::Element*()> view;
|
||||||
Fn<Ui::ChatPaintContext()> paintContext;
|
Fn<Ui::ChatPaintContext()> paintContext;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue