Drafts always shown in dialogs list when no unread messages in the chat.

Edition of any message to service message "history cleared".
This commit is contained in:
John Preston 2016-06-13 21:42:25 +03:00
parent 7c34872a48
commit 044e9221e8
6 changed files with 175 additions and 46 deletions

View file

@ -1096,6 +1096,12 @@ namespace {
} }
} }
void updateEditedMessageToEmpty(PeerId peerId, MsgId msgId) {
if (auto existing = App::histItemById(peerToChannel(peerId), msgId)) {
existing->applyEditionToEmpty();
}
}
void addSavedGif(DocumentData *doc) { void addSavedGif(DocumentData *doc) {
SavedGifs &saved(cRefSavedGifs()); SavedGifs &saved(cRefSavedGifs());
int32 index = saved.indexOf(doc); int32 index = saved.indexOf(doc);

View file

@ -77,6 +77,7 @@ namespace App {
void feedParticipantAdmin(const MTPDupdateChatParticipantAdmin &d, bool emitPeerUpdated = true); void feedParticipantAdmin(const MTPDupdateChatParticipantAdmin &d, bool emitPeerUpdated = true);
bool checkEntitiesAndViewsUpdate(const MTPDmessage &m); // returns true if item found and it is not detached bool checkEntitiesAndViewsUpdate(const MTPDmessage &m); // returns true if item found and it is not detached
void updateEditedMessage(const MTPDmessage &m); void updateEditedMessage(const MTPDmessage &m);
void updateEditedMessageToEmpty(PeerId peerId, MsgId msgId);
void addSavedGif(DocumentData *doc); void addSavedGif(DocumentData *doc);
void checkSavedGif(HistoryItem *item); void checkSavedGif(HistoryItem *item);
void feedMsgs(const QVector<MTPMessage> &msgs, NewMessageType type); void feedMsgs(const QVector<MTPMessage> &msgs, NewMessageType type);

View file

@ -52,7 +52,7 @@ void paintRowDate(Painter &p, const QDateTime &date, QRect &rectForName, bool ac
} }
template <typename PaintItemCallback> template <typename PaintItemCallback>
void paintRow(Painter &p, History *history, HistoryItem *item, Data::Draft *draft, int w, bool active, bool selected, bool onlyBackground, PaintItemCallback paintItemCallback) { void paintRow(Painter &p, History *history, HistoryItem *item, Data::Draft *draft, QDateTime date, int w, bool active, bool selected, bool onlyBackground, PaintItemCallback paintItemCallback) {
QRect fullRect(0, 0, w, st::dialogsRowHeight); QRect fullRect(0, 0, w, st::dialogsRowHeight);
p.fillRect(fullRect, active ? st::dialogsBgActive : (selected ? st::dialogsBgOver : st::dialogsBg)); p.fillRect(fullRect, active ? st::dialogsBgActive : (selected ? st::dialogsBgOver : st::dialogsBg));
if (onlyBackground) return; if (onlyBackground) return;
@ -75,7 +75,7 @@ void paintRow(Painter &p, History *history, HistoryItem *item, Data::Draft *draf
int texttop = st::dialogsPadding.y() + st::msgNameFont->height + st::dialogsSkip; int texttop = st::dialogsPadding.y() + st::msgNameFont->height + st::dialogsSkip;
if (draft) { if (draft) {
paintRowDate(p, draft->date, rectForName, active); paintRowDate(p, date, rectForName, active);
// draw check // draw check
if (draft->saveRequestId) { if (draft->saveRequestId) {
@ -110,7 +110,7 @@ void paintRow(Painter &p, History *history, HistoryItem *item, Data::Draft *draf
history->typingText.drawElided(p, nameleft, texttop, namewidth); history->typingText.drawElided(p, nameleft, texttop, namewidth);
} }
} else if (!item->isEmpty()) { } else if (!item->isEmpty()) {
paintRowDate(p, item->date, rectForName, active); paintRowDate(p, date, rectForName, active);
// draw check // draw check
if (item->needCheck()) { if (item->needCheck()) {
@ -211,20 +211,33 @@ void RowPainter::paint(Painter &p, const Row *row, int w, bool active, bool sele
auto history = row->history(); auto history = row->history();
auto item = history->lastMsg; auto item = history->lastMsg;
auto cloudDraft = history->cloudDraft(); auto cloudDraft = history->cloudDraft();
if (item && cloudDraft && cloudDraft->date < item->date) { if (Data::draftIsNull(cloudDraft)) {
cloudDraft = nullptr;
}
auto displayDate = [item, cloudDraft]() {
if (item) {
if (cloudDraft) {
return (item->date > cloudDraft->date) ? item->date : cloudDraft->date;
}
return item->date;
}
return cloudDraft ? cloudDraft->date : QDateTime();
};
int unreadCount = history->unreadCount();
if (history->peer->migrateFrom()) {
if (auto migrated = App::historyLoaded(history->peer->migrateFrom()->id)) {
unreadCount += migrated->unreadCount();
}
}
if (item && cloudDraft && unreadCount > 0) {
cloudDraft = nullptr; // Draw item, if draft is older. cloudDraft = nullptr; // Draw item, if draft is older.
} }
paintRow(p, history, item, cloudDraft, w, active, selected, onlyBackground, [&p, w, active, history](int nameleft, int namewidth, HistoryItem *item) { paintRow(p, history, item, cloudDraft, displayDate(), w, active, selected, onlyBackground, [&p, w, active, history, unreadCount](int nameleft, int namewidth, HistoryItem *item) {
int32 unread = history->unreadCount();
if (history->peer->migrateFrom()) {
if (History *h = App::historyLoaded(history->peer->migrateFrom()->id)) {
unread += h->unreadCount();
}
}
int availableWidth = namewidth; int availableWidth = namewidth;
int texttop = st::dialogsPadding.y() + st::msgNameFont->height + st::dialogsSkip; int texttop = st::dialogsPadding.y() + st::msgNameFont->height + st::dialogsSkip;
if (unread) { if (unreadCount) {
auto counter = QString::number(unread); auto counter = QString::number(unreadCount);
auto mutedCounter = history->mute(); auto mutedCounter = history->mute();
int unreadRight = w - st::dialogsPadding.x(); int unreadRight = w - st::dialogsPadding.x();
int unreadTop = texttop + st::dialogsTextFont->ascent - st::dialogsUnreadFont->ascent - st::dialogsUnreadTop; int unreadTop = texttop + st::dialogsTextFont->ascent - st::dialogsUnreadFont->ascent - st::dialogsUnreadTop;
@ -244,7 +257,7 @@ void RowPainter::paint(Painter &p, const Row *row, int w, bool active, bool sele
void RowPainter::paint(Painter &p, const FakeRow *row, int w, bool active, bool selected, bool onlyBackground) { void RowPainter::paint(Painter &p, const FakeRow *row, int w, bool active, bool selected, bool onlyBackground) {
auto item = row->item(); auto item = row->item();
auto history = item->history(); auto history = item->history();
paintRow(p, history, item, nullptr, w, active, selected, onlyBackground, [&p, row, active](int nameleft, int namewidth, HistoryItem *item) { paintRow(p, history, item, nullptr, item->date, w, active, selected, onlyBackground, [&p, row, active](int nameleft, int namewidth, HistoryItem *item) {
int lastWidth = namewidth, texttop = st::dialogsPadding.y() + st::msgNameFont->height + st::dialogsSkip; int lastWidth = namewidth, texttop = st::dialogsPadding.y() + st::msgNameFont->height + st::dialogsSkip;
item->drawInDialog(p, QRect(nameleft, texttop, lastWidth, st::dialogsTextFont->height), active, row->_cacheFor, row->_cache); item->drawInDialog(p, QRect(nameleft, texttop, lastWidth, st::dialogsTextFont->height), active, row->_cacheFor, row->_cache);
}); });

View file

@ -2641,6 +2641,49 @@ void HistoryItem::finishCreate() {
App::historyRegItem(this); App::historyRegItem(this);
} }
void HistoryItem::finishEdition(int oldKeyboardTop) {
setPendingInitDimensions();
if (App::main()) {
App::main()->dlgUpdated(history(), id);
}
// invalidate cache for drawInDialog
if (history()->textCachedFor == this) {
history()->textCachedFor = nullptr;
}
if (oldKeyboardTop >= 0) {
if (auto keyboard = Get<HistoryMessageReplyMarkup>()) {
keyboard->oldTop = oldKeyboardTop;
}
}
App::historyUpdateDependent(this);
}
void HistoryItem::finishEditionToEmpty() {
recountDisplayDate();
finishEdition(-1);
_history->removeNotification(this);
if (history()->isChannel()) {
if (history()->peer->isMegagroup() && history()->peer->asChannel()->mgInfo->pinnedMsgId == id) {
history()->peer->asChannel()->mgInfo->pinnedMsgId = 0;
}
}
if (history()->lastKeyboardId == id) {
history()->clearLastKeyboard();
if (App::main()) App::main()->updateBotKeyboard(history());
}
if ((!out() || isPost()) && unread() && history()->unreadCount() > 0) {
history()->setUnreadCount(history()->unreadCount() - 1);
}
if (auto next = nextItem()) {
next->previousItemChanged();
}
}
void HistoryItem::clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active) { void HistoryItem::clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active) {
if (auto markup = Get<HistoryMessageReplyMarkup>()) { if (auto markup = Get<HistoryMessageReplyMarkup>()) {
if (markup->inlineKeyboard) { if (markup->inlineKeyboard) {
@ -2712,8 +2755,12 @@ void HistoryItem::previousItemChanged() {
void HistoryItem::recountAttachToPrevious() { void HistoryItem::recountAttachToPrevious() {
bool attach = false; bool attach = false;
if (!isPost() && !Has<HistoryMessageDate>() && !Has<HistoryMessageUnreadBar>()) { if (!isPost() && !Has<HistoryMessageDate>() && !Has<HistoryMessageUnreadBar>()) {
if (HistoryItem *prev = previous()) { if (auto previos = previousItem()) {
attach = !prev->isPost() && !prev->serviceMsg() && prev->from() == from() && qAbs(prev->date.secsTo(date)) < AttachMessageToPreviousSecondsDelta; attach = !previos->isPost()
&& !previos->serviceMsg()
&& !previos->isEmpty()
&& previos->from() == from()
&& (qAbs(previos->date.secsTo(date)) < AttachMessageToPreviousSecondsDelta);
} }
} }
if (attach && !(_flags & MTPDmessage_ClientFlag::f_attach_to_previous)) { if (attach && !(_flags & MTPDmessage_ClientFlag::f_attach_to_previous)) {
@ -2861,8 +2908,8 @@ void HistoryItem::recountDisplayDate() {
bool displayingDate = ([this]() { bool displayingDate = ([this]() {
if (isEmpty()) return false; if (isEmpty()) return false;
if (auto prev = previous()) { if (auto previous = previousItem()) {
return prev->isEmpty() || (prev->date.date() != date.date()); return previous->isEmpty() || (previous->date.date() != date.date());
} }
return true; return true;
})(); })();
@ -6754,10 +6801,13 @@ void HistoryMessage::initDimensions() {
if (_namew > _maxw) _maxw = _namew; if (_namew > _maxw) _maxw = _namew;
} }
} }
} else { } else if (_media) {
_media->initDimensions(); _media->initDimensions();
_maxw = _media->maxWidth(); _maxw = _media->maxWidth();
_minh = _media->minHeight(); _minh = _media->minHeight();
} else {
_maxw = st::msgMinWidth;
_minh = 0;
} }
if (reply && !_text.isEmpty()) { if (reply && !_text.isEmpty()) {
int replyw = st::msgPadding.left() + reply->_maxReplyWidth - st::msgReplyPadding.left() - st::msgReplyPadding.right() + st::msgPadding.right(); int replyw = st::msgPadding.left() + reply->_maxReplyWidth - st::msgReplyPadding.left() - st::msgReplyPadding.right() + st::msgPadding.right();
@ -6841,23 +6891,16 @@ void HistoryMessage::applyEdition(const MTPDmessage &message) {
setReplyMarkup(message.has_reply_markup() ? (&message.vreply_markup) : nullptr); setReplyMarkup(message.has_reply_markup() ? (&message.vreply_markup) : nullptr);
setViewsCount(message.has_views() ? message.vviews.v : -1); setViewsCount(message.has_views() ? message.vviews.v : -1);
setPendingInitDimensions(); finishEdition(keyboardTop);
if (App::main()) { }
App::main()->dlgUpdated(history(), id);
}
// invalidate cache for drawInDialog void HistoryMessage::applyEditionToEmpty() {
if (history()->textCachedFor == this) { setEmptyText();
history()->textCachedFor = nullptr; setMedia(nullptr);
} setReplyMarkup(nullptr);
setViewsCount(-1);
if (keyboardTop >= 0) { finishEditionToEmpty();
if (auto keyboard = Get<HistoryMessageReplyMarkup>()) {
keyboard->oldTop = keyboardTop;
}
}
App::historyUpdateDependent(this);
} }
void HistoryMessage::updateMedia(const MTPMessageMedia *media) { void HistoryMessage::updateMedia(const MTPMessageMedia *media) {
@ -6999,6 +7042,15 @@ void HistoryMessage::setText(const TextWithEntities &textWithEntities) {
_textHeight = 0; _textHeight = 0;
} }
void HistoryMessage::setEmptyText() {
textstyleSet(&((out() && !isPost()) ? st::outTextStyle : st::inTextStyle));
_text.setMarkedText(st::msgFont, { QString(), EntitiesInText() }, itemTextOptions(this));
textstyleRestore();
_textWidth = -1;
_textHeight = 0;
}
void HistoryMessage::setReplyMarkup(const MTPReplyMarkup *markup) { void HistoryMessage::setReplyMarkup(const MTPReplyMarkup *markup) {
if (!markup) { if (!markup) {
if (_flags & MTPDmessage::Flag::f_reply_markup) { if (_flags & MTPDmessage::Flag::f_reply_markup) {
@ -7276,7 +7328,7 @@ void HistoryMessage::draw(Painter &p, const QRect &r, TextSelection selection, u
} else { } else {
HistoryMessage::drawInfo(p, r.x() + r.width(), r.y() + r.height(), 2 * r.x() + r.width(), selected, InfoDisplayDefault); HistoryMessage::drawInfo(p, r.x() + r.width(), r.y() + r.height(), 2 * r.x() + r.width(), selected, InfoDisplayDefault);
} }
} else { } else if (_media) {
int32 top = marginTop(); int32 top = marginTop();
p.translate(left, top); p.translate(left, top);
_media->draw(p, r.translated(-left, -top), toMediaSelection(selection), ms); _media->draw(p, r.translated(-left, -top), toMediaSelection(selection), ms);
@ -7437,8 +7489,10 @@ int HistoryMessage::performResizeGetHeight(int width) {
} }
reply->resize(w - st::msgPadding.left() - st::msgPadding.right()); reply->resize(w - st::msgPadding.left() - st::msgPadding.right());
} }
} else { } else if (_media) {
_height = _media->resizeGetHeight(width); _height = _media->resizeGetHeight(width);
} else {
_height = 0;
} }
if (auto keyboard = inlineReplyKeyboard()) { if (auto keyboard = inlineReplyKeyboard()) {
int32 l = 0, w = 0; int32 l = 0, w = 0;
@ -7462,8 +7516,10 @@ bool HistoryMessage::hasPoint(int x, int y) const {
int top = marginTop(); int top = marginTop();
QRect r(left, top, width, height - top - marginBottom()); QRect r(left, top, width, height - top - marginBottom());
return r.contains(x, y); return r.contains(x, y);
} else { } else if (_media) {
return _media->hasPoint(x - left, y - marginTop()); return _media->hasPoint(x - left, y - marginTop());
} else {
return false;
} }
} }
@ -7579,7 +7635,7 @@ HistoryTextState HistoryMessage::getState(int x, int y, HistoryStateRequest requ
if (inDate) { if (inDate) {
result.cursor = HistoryInDateCursorState; result.cursor = HistoryInDateCursorState;
} }
} else { } else if (_media) {
result = _media->getState(x - left, y - marginTop(), request); result = _media->getState(x - left, y - marginTop(), request);
result.symbol += _text.length(); result.symbol += _text.length();
} }
@ -7611,7 +7667,7 @@ void HistoryMessage::drawInDialog(Painter &p, const QRect &r, bool act, const Hi
if (cacheFor != this) { if (cacheFor != this) {
cacheFor = this; cacheFor = this;
QString msg(inDialogsText()); QString msg(inDialogsText());
if ((!_history->peer->isUser() || out()) && !isPost()) { if ((!_history->peer->isUser() || out()) && !isPost() && !isEmpty()) {
TextCustomTagsMap custom; TextCustomTagsMap custom;
custom.insert(QChar('c'), qMakePair(textcmdStartLink(1), textcmdStopLink())); custom.insert(QChar('c'), qMakePair(textcmdStartLink(1), textcmdStopLink()));
msg = lng_message_with_from(lt_from, textRichPrepare((author() == App::self()) ? lang(lng_from_you) : author()->shortName()), lt_message, textRichPrepare(msg)); msg = lng_message_with_from(lt_from, textRichPrepare((author() == App::self()) ? lang(lng_from_you) : author()->shortName()), lt_message, textRichPrepare(msg));
@ -7644,7 +7700,7 @@ bool HistoryMessage::displayFromPhoto() const {
} }
bool HistoryMessage::hasFromPhoto() const { bool HistoryMessage::hasFromPhoto() const {
return (Adaptive::Wide() || (!out() && !history()->peer->isUser())) && !isPost(); return (Adaptive::Wide() || (!out() && !history()->peer->isUser())) && !isPost() && !isEmpty();
} }
HistoryMessage::~HistoryMessage() { HistoryMessage::~HistoryMessage() {
@ -8109,6 +8165,25 @@ QString HistoryService::notificationText() const {
return msg; return msg;
} }
void HistoryService::applyEditionToEmpty() {
TextWithEntities textWithEntities = { QString(), EntitiesInText() };
setServiceText(QString());
removeMedia();
finishEditionToEmpty();
}
void HistoryService::removeMedia() {
if (!_media) return;
bool mediaWasDisplayed = _media->isDisplayed();
_media.clear();
if (mediaWasDisplayed) {
_textWidth = -1;
_textHeight = 0;
}
}
int32 HistoryService::addToOverview(AddToOverviewMethod method) { int32 HistoryService::addToOverview(AddToOverviewMethod method) {
if (!indexInOverview()) return 0; if (!indexInOverview()) return 0;

View file

@ -608,11 +608,16 @@ public:
int32 y, height; int32 y, height;
History *history; History *history;
HistoryBlock *previous() const { HistoryBlock *previousBlock() const {
t_assert(_indexInHistory >= 0); t_assert(_indexInHistory >= 0);
return (_indexInHistory > 0) ? history->blocks.at(_indexInHistory - 1) : nullptr; return (_indexInHistory > 0) ? history->blocks.at(_indexInHistory - 1) : nullptr;
} }
HistoryBlock *nextBlock() const {
t_assert(_indexInHistory >= 0);
return (_indexInHistory + 1 < history->blocks.size()) ? history->blocks.at(_indexInHistory + 1) : nullptr;
}
void setIndexInHistory(int index) { void setIndexInHistory(int index) {
_indexInHistory = index; _indexInHistory = index;
} }
@ -1189,6 +1194,8 @@ public:
} }
virtual void applyEdition(const MTPDmessage &message) { virtual void applyEdition(const MTPDmessage &message) {
} }
virtual void applyEditionToEmpty() {
}
virtual void updateMedia(const MTPMessageMedia *media) { virtual void updateMedia(const MTPMessageMedia *media) {
} }
virtual int32 addToOverview(AddToOverviewMethod method) { virtual int32 addToOverview(AddToOverviewMethod method) {
@ -1415,6 +1422,9 @@ protected:
virtual int resizeGetHeight_(int width) = 0; virtual int resizeGetHeight_(int width) = 0;
void finishEdition(int oldKeyboardTop);
void finishEditionToEmpty();
PeerData *_from; PeerData *_from;
History *_history; History *_history;
HistoryBlock *_block = nullptr; HistoryBlock *_block = nullptr;
@ -1423,14 +1433,26 @@ protected:
mutable int32 _authorNameVersion; mutable int32 _authorNameVersion;
HistoryItem *previous() const { HistoryItem *previousItem() const {
if (_block && _indexInBlock >= 0) { if (_block && _indexInBlock >= 0) {
if (_indexInBlock > 0) { if (_indexInBlock > 0) {
return _block->items.at(_indexInBlock - 1); return _block->items.at(_indexInBlock - 1);
} }
if (HistoryBlock *previousBlock = _block->previous()) { if (auto previous = _block->previousBlock()) {
t_assert(!previousBlock->items.isEmpty()); t_assert(!previous->items.isEmpty());
return previousBlock->items.back(); return previous->items.back();
}
}
return nullptr;
}
HistoryItem *nextItem() const {
if (_block && _indexInBlock >= 0) {
if (_indexInBlock + 1 < _block->items.size()) {
return _block->items.at(_indexInBlock + 1);
}
if (auto next = _block->nextBlock()) {
t_assert(!next->items.isEmpty());
return next->items.front();
} }
} }
return nullptr; return nullptr;
@ -2530,7 +2552,7 @@ public:
return _text.isEmpty(); return _text.isEmpty();
} }
bool drawBubble() const { bool drawBubble() const {
return _media ? (!emptyText() || _media->needsBubble()) : true; return _media ? (!emptyText() || _media->needsBubble()) : !isEmpty();
} }
bool hasBubble() const override { bool hasBubble() const override {
return drawBubble(); return drawBubble();
@ -2575,6 +2597,7 @@ public:
QString notificationText() const override; QString notificationText() const override;
void applyEdition(const MTPDmessage &message) override; void applyEdition(const MTPDmessage &message) override;
void applyEditionToEmpty() override;
void updateMedia(const MTPMessageMedia *media) override; void updateMedia(const MTPMessageMedia *media) override;
int32 addToOverview(AddToOverviewMethod method) override; int32 addToOverview(AddToOverviewMethod method) override;
void eraseFromOverview() override; void eraseFromOverview() override;
@ -2650,6 +2673,8 @@ private:
HistoryMessage(History *history, MsgId msgId, MTPDmessage::Flags flags, MsgId replyTo, int32 viaBotId, QDateTime date, int32 from, PhotoData *photo, const QString &caption, const MTPReplyMarkup &markup); // local photo HistoryMessage(History *history, MsgId msgId, MTPDmessage::Flags flags, MsgId replyTo, int32 viaBotId, QDateTime date, int32 from, PhotoData *photo, const QString &caption, const MTPReplyMarkup &markup); // local photo
friend class HistoryItemInstantiated<HistoryMessage>; friend class HistoryItemInstantiated<HistoryMessage>;
void setEmptyText();
void initDimensions() override; void initDimensions() override;
int resizeGetHeight_(int width) override; int resizeGetHeight_(int width) override;
int performResizeGetHeight(int width); int performResizeGetHeight(int width);
@ -2772,6 +2797,8 @@ public:
void drawInDialog(Painter &p, const QRect &r, bool act, const HistoryItem *&cacheFor, Text &cache) const override; void drawInDialog(Painter &p, const QRect &r, bool act, const HistoryItem *&cacheFor, Text &cache) const override;
QString notificationText() const override; QString notificationText() const override;
void applyEditionToEmpty() override;
int32 addToOverview(AddToOverviewMethod method) override; int32 addToOverview(AddToOverviewMethod method) override;
void eraseFromOverview() override; void eraseFromOverview() override;
@ -2799,6 +2826,8 @@ protected:
void initDimensions() override; void initDimensions() override;
int resizeGetHeight_(int width) override; int resizeGetHeight_(int width) override;
void removeMedia();
void setMessageByAction(const MTPmessageAction &action); void setMessageByAction(const MTPmessageAction &action);
bool updatePinned(bool force = false); bool updatePinned(bool force = false);
bool updatePinnedText(const QString *pfrom = nullptr, QString *ptext = nullptr); bool updatePinnedText(const QString *pfrom = nullptr, QString *ptext = nullptr);

View file

@ -4507,6 +4507,11 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
// update before applying skipped // update before applying skipped
if (d.vmessage.type() == mtpc_message) { // apply message edit if (d.vmessage.type() == mtpc_message) { // apply message edit
App::updateEditedMessage(d.vmessage.c_message()); App::updateEditedMessage(d.vmessage.c_message());
} else if (d.vmessage.type() == mtpc_messageService) {
auto &message = d.vmessage.c_messageService();
if (message.vaction.type() == mtpc_messageActionHistoryClear) {
App::updateEditedMessageToEmpty(peerFromMessage(d.vmessage), message.vid.v);
}
} }
ptsApplySkippedUpdates(); ptsApplySkippedUpdates();
} break; } break;