Fix crash when accessing a deleted item view.

This commit is contained in:
John Preston 2018-03-09 14:44:42 +03:00
parent 73c0c4507a
commit 6bd5301828
6 changed files with 34 additions and 5 deletions

View file

@ -21,7 +21,7 @@ int OnlinePhraseChangeInSeconds(TimeId online, TimeId now) {
if (-online > now) {
return (-online - now);
}
return std::numeric_limits<int32>::max();
return std::numeric_limits<TimeId>::max();
}
if (online > now) {
return online - now;
@ -36,7 +36,7 @@ int OnlinePhraseChangeInSeconds(TimeId online, TimeId now) {
}
const auto nowFull = ParseDateTime(now);
const auto tomorrow = QDateTime(nowFull.date().addDays(1));
return static_cast<int32>(nowFull.secsTo(tomorrow));
return std::max(static_cast<TimeId>(nowFull.secsTo(tomorrow)), 0);
}
base::optional<QString> OnlineTextSpecial(not_null<UserData*> user) {

View file

@ -273,6 +273,14 @@ rpl::producer<not_null<const HistoryItem*>> Session::itemRemoved() const {
return _itemRemoved.events();
}
void Session::notifyViewRemoved(not_null<const ViewElement*> view) {
_viewRemoved.fire_copy(view);
}
rpl::producer<not_null<const ViewElement*>> Session::viewRemoved() const {
return _viewRemoved.events();
}
void Session::notifyHistoryUnloaded(not_null<const History*> history) {
_historyUnloaded.fire_copy(history);
}

View file

@ -87,6 +87,8 @@ public:
void notifyItemRemoved(not_null<const HistoryItem*> item);
[[nodiscard]] rpl::producer<not_null<const HistoryItem*>> itemRemoved() const;
void notifyViewRemoved(not_null<const ViewElement*> view);
[[nodiscard]] rpl::producer<not_null<const ViewElement*>> viewRemoved() const;
void notifyHistoryCleared(not_null<const History*> history);
[[nodiscard]] rpl::producer<not_null<const History*>> historyCleared() const;
void notifyHistoryChangeDelayed(not_null<History*> history);
@ -468,6 +470,7 @@ private:
rpl::event_stream<not_null<HistoryItem*>> _itemViewRefreshRequest;
rpl::event_stream<not_null<HistoryItem*>> _animationPlayInlineRequest;
rpl::event_stream<not_null<const HistoryItem*>> _itemRemoved;
rpl::event_stream<not_null<const ViewElement*>> _viewRemoved;
rpl::event_stream<not_null<const History*>> _historyUnloaded;
rpl::event_stream<not_null<const History*>> _historyCleared;
base::flat_set<not_null<History*>> _historiesChanged;

View file

@ -139,10 +139,14 @@ HistoryInner::HistoryInner(
) | rpl::start_with_next(
[this](auto item) { itemRemoved(item); },
lifetime());
Auth().data().viewRemoved(
) | rpl::start_with_next(
[this](auto view) { viewRemoved(view); },
lifetime());
Auth().data().itemViewRefreshRequest(
) | rpl::start_with_next([this](auto item) {
refreshView(item);
}, lifetime());
) | rpl::start_with_next(
[this](auto item) { refreshView(item); },
lifetime());
rpl::merge(
Auth().data().historyUnloaded(),
Auth().data().historyCleared()
@ -1222,6 +1226,18 @@ void HistoryInner::itemRemoved(not_null<const HistoryItem*> item) {
mouseActionUpdate();
}
void HistoryInner::viewRemoved(not_null<const Element*> view) {
if (_dragSelFrom == view) {
_dragSelFrom = nullptr;
}
if (_dragSelTo == view) {
_dragSelTo = nullptr;
}
if (_scrollDateLastItem == view) {
_scrollDateLastItem = nullptr;
}
}
void HistoryInner::refreshView(not_null<HistoryItem*> item) {
const auto dragSelFrom = (_dragSelFrom && _dragSelFrom->data() == item);
const auto dragSelTo = (_dragSelTo && _dragSelTo->data() == item);

View file

@ -214,6 +214,7 @@ private:
void toggleFavedSticker(not_null<DocumentData*> document);
void itemRemoved(not_null<const HistoryItem*> item);
void viewRemoved(not_null<const Element*> view);
void refreshView(not_null<HistoryItem*> item);
void touchResetSpeed();

View file

@ -268,6 +268,7 @@ void HistoryItem::refreshMainView() {
void HistoryItem::removeMainView() {
if (const auto view = mainView()) {
Auth().data().notifyHistoryChangeDelayed(_history);
Auth().data().notifyViewRemoved(view);
view->removeFromBlock();
}
}