moving left userpics at the top of the conversation window, beta 9034002

This commit is contained in:
John Preston 2016-03-22 22:43:47 +03:00
parent ee946025d6
commit e45de88bd6
7 changed files with 305 additions and 247 deletions

View File

@ -23,7 +23,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
static const int32 AppVersion = 9034; static const int32 AppVersion = 9034;
static const wchar_t *AppVersionStr = L"0.9.34"; static const wchar_t *AppVersionStr = L"0.9.34";
static const bool DevVersion = false; static const bool DevVersion = false;
#define BETA_VERSION (9034001ULL) // just comment this line to build public version #define BETA_VERSION (9034002ULL) // just comment this line to build public version
static const wchar_t *AppNameOld = L"Telegram Win (Unofficial)"; static const wchar_t *AppNameOld = L"Telegram Win (Unofficial)";
static const wchar_t *AppName = L"Telegram Desktop"; static const wchar_t *AppName = L"Telegram Desktop";
@ -101,8 +101,8 @@ enum {
MediaOverviewStartPerPage = 5, MediaOverviewStartPerPage = 5,
MediaOverviewPreloadCount = 4, MediaOverviewPreloadCount = 4,
// a new message from the same sender is attached to previous within 30 seconds // a new message from the same sender is attached to previous within 15 minutes
AttachMessageToPreviousSecondsDelta = 30, AttachMessageToPreviousSecondsDelta = 900,
AudioVoiceMsgSimultaneously = 4, AudioVoiceMsgSimultaneously = 4,
AudioSongSimultaneously = 4, AudioSongSimultaneously = 4,

View File

@ -2843,7 +2843,7 @@ void HistoryItem::recountAttachToPrevious() {
bool attach = false; bool attach = false;
if (!isPost() && !Is<HistoryMessageDate>() && !Is<HistoryMessageUnreadBar>()) { if (!isPost() && !Is<HistoryMessageDate>() && !Is<HistoryMessageUnreadBar>()) {
if (HistoryItem *prev = previous()) { if (HistoryItem *prev = previous()) {
attach = !prev->isPost() && !prev->serviceMsg() && prev->from() == from()/* && qAbs(prev->date.secsTo(date)) < AttachMessageToPreviousSecondsDelta*/; attach = !prev->isPost() && !prev->serviceMsg() && prev->from() == from() && qAbs(prev->date.secsTo(date)) < AttachMessageToPreviousSecondsDelta;
} }
} }
if (attach && !(_flags & MTPDmessage_ClientFlag::f_attach_to_previous)) { if (attach && !(_flags & MTPDmessage_ClientFlag::f_attach_to_previous)) {
@ -2860,14 +2860,6 @@ void HistoryItem::setId(MsgId newId) {
id = newId; id = newId;
} }
bool HistoryItem::displayFromPhoto() const {
return hasFromPhoto() && !isAttachedToPrevious();
}
bool HistoryItem::hasFromPhoto() const {
return (Adaptive::Wide() || (!out() && !history()->peer->isUser())) && !isPost();
}
bool HistoryItem::canEdit(const QDateTime &cur) const { bool HistoryItem::canEdit(const QDateTime &cur) const {
ChannelData *channel = _history->peer->asChannel(); ChannelData *channel = _history->peer->asChannel();
int32 s = date.secsTo(cur); int32 s = date.secsTo(cur);
@ -6039,10 +6031,7 @@ void HistoryMessageForwarded::create(const HistoryMessageVia *via) const {
HistoryMessage::HistoryMessage(History *history, const MTPDmessage &msg) : HistoryMessage::HistoryMessage(History *history, const MTPDmessage &msg) :
HistoryItem(history, msg.vid.v, msg.vflags.v, ::date(msg.vdate), msg.has_from_id() ? msg.vfrom_id.v : 0) HistoryItem(history, msg.vid.v, msg.vflags.v, ::date(msg.vdate), msg.has_from_id() ? msg.vfrom_id.v : 0)
, _text(st::msgMinWidth) , _text(st::msgMinWidth) {
, _textWidth(0)
, _textHeight(0)
, _media(0) {
PeerId authorOriginalId = 0, fromOriginalId = 0; PeerId authorOriginalId = 0, fromOriginalId = 0;
MsgId originalId = 0; MsgId originalId = 0;
if (msg.has_fwd_from() && msg.vfwd_from.type() == mtpc_messageFwdHeader) { if (msg.has_fwd_from() && msg.vfwd_from.type() == mtpc_messageFwdHeader) {
@ -6061,11 +6050,7 @@ HistoryMessage::HistoryMessage(History *history, const MTPDmessage &msg) :
} }
HistoryMessage::HistoryMessage(History *history, MsgId id, MTPDmessage::Flags flags, QDateTime date, int32 from, HistoryMessage *fwd) HistoryMessage::HistoryMessage(History *history, MsgId id, MTPDmessage::Flags flags, QDateTime date, int32 from, HistoryMessage *fwd)
: HistoryItem(history, id, newForwardedFlags(history->peer, from, fwd) | flags, date, from) : HistoryItem(history, id, newForwardedFlags(history->peer, from, fwd) | flags, date, from) {
, _text(st::msgMinWidth)
, _textWidth(0)
, _textHeight(0)
, _media(nullptr) {
UserData *fwdViaBot = fwd->viaBot(); UserData *fwdViaBot = fwd->viaBot();
int32 viaBotId = fwdViaBot ? peerToUser(fwdViaBot->id) : 0; int32 viaBotId = fwdViaBot ? peerToUser(fwdViaBot->id) : 0;
int32 fwdViewsCount = fwd->viewsCount(), views = (fwdViewsCount > 0) ? fwdViewsCount : (isPost() ? 1 : -1); int32 fwdViewsCount = fwd->viewsCount(), views = (fwdViewsCount > 0) ? fwdViewsCount : (isPost() ? 1 : -1);
@ -6079,22 +6064,14 @@ HistoryMessage::HistoryMessage(History *history, MsgId id, MTPDmessage::Flags fl
} }
HistoryMessage::HistoryMessage(History *history, MsgId id, MTPDmessage::Flags flags, int32 viaBotId, QDateTime date, int32 from, const QString &msg, const EntitiesInText &entities) HistoryMessage::HistoryMessage(History *history, MsgId id, MTPDmessage::Flags flags, int32 viaBotId, QDateTime date, int32 from, const QString &msg, const EntitiesInText &entities)
: HistoryItem(history, id, flags, date, (flags & MTPDmessage::Flag::f_from_id) ? from : 0) : HistoryItem(history, id, flags, date, (flags & MTPDmessage::Flag::f_from_id) ? from : 0) {
, _text(st::msgMinWidth)
, _textWidth(0)
, _textHeight(0)
, _media(nullptr) {
createInterfaces((flags & MTPDmessage::Flag::f_via_bot_id) ? viaBotId : 0, isPost() ? 1 : -1); createInterfaces((flags & MTPDmessage::Flag::f_via_bot_id) ? viaBotId : 0, isPost() ? 1 : -1);
setText(msg, entities); setText(msg, entities);
} }
HistoryMessage::HistoryMessage(History *history, MsgId msgId, MTPDmessage::Flags flags, int32 viaBotId, QDateTime date, int32 from, DocumentData *doc, const QString &caption) : HistoryMessage::HistoryMessage(History *history, MsgId msgId, MTPDmessage::Flags flags, int32 viaBotId, QDateTime date, int32 from, DocumentData *doc, const QString &caption) :
HistoryItem(history, msgId, flags, date, (flags & MTPDmessage::Flag::f_from_id) ? from : 0) HistoryItem(history, msgId, flags, date, (flags & MTPDmessage::Flag::f_from_id) ? from : 0) {
, _text(st::msgMinWidth)
, _textWidth(0)
, _textHeight(0)
, _media(nullptr) {
createInterfaces((flags & MTPDmessage::Flag::f_via_bot_id) ? viaBotId : 0, isPost() ? 1 : -1); createInterfaces((flags & MTPDmessage::Flag::f_via_bot_id) ? viaBotId : 0, isPost() ? 1 : -1);
initMediaFromDocument(doc, caption); initMediaFromDocument(doc, caption);
@ -6102,11 +6079,7 @@ HistoryItem(history, msgId, flags, date, (flags & MTPDmessage::Flag::f_from_id)
} }
HistoryMessage::HistoryMessage(History *history, MsgId msgId, MTPDmessage::Flags flags, int32 viaBotId, QDateTime date, int32 from, PhotoData *photo, const QString &caption) : HistoryMessage::HistoryMessage(History *history, MsgId msgId, MTPDmessage::Flags flags, int32 viaBotId, QDateTime date, int32 from, PhotoData *photo, const QString &caption) :
HistoryItem(history, msgId, flags, date, (flags & MTPDmessage::Flag::f_from_id) ? from : 0) HistoryItem(history, msgId, flags, date, (flags & MTPDmessage::Flag::f_from_id) ? from : 0) {
, _text(st::msgMinWidth)
, _textWidth(0)
, _textHeight(0)
, _media(nullptr) {
createInterfaces((flags & MTPDmessage::Flag::f_via_bot_id) ? viaBotId : 0, isPost() ? 1 : -1); createInterfaces((flags & MTPDmessage::Flag::f_via_bot_id) ? viaBotId : 0, isPost() ? 1 : -1);
_media = new HistoryPhoto(photo, caption, this); _media = new HistoryPhoto(photo, caption, this);
@ -6598,14 +6571,11 @@ void HistoryMessage::draw(Painter &p, const QRect &r, uint32 selection, uint64 m
textstyleSet(&(outbg ? st::outTextStyle : st::inTextStyle)); textstyleSet(&(outbg ? st::outTextStyle : st::inTextStyle));
if (displayFromPhoto()) { //if (displayFromPhoto()) {
int photoleft = left + ((outbg && !Adaptive::Wide()) ? (width + (st::msgPhotoSkip - st::msgPhotoSize)) : (-st::msgPhotoSkip)); // int photoleft = left + ((outbg && !Adaptive::Wide()) ? (width + (st::msgPhotoSkip - st::msgPhotoSize)) : (-st::msgPhotoSkip));
int phototop = marginTop(); // int phototop = marginTop();
// if (history()->scrollTopItem == this) { // author()->paintUserpic(p, st::msgPhotoSize, photoleft, phototop);
// phototop = qMax(qMin(history()->scrollTopOffset, _height - marginBottom() - int(st::msgPhotoSize)), phototop); //}
// }
author()->paintUserpic(p, st::msgPhotoSize, photoleft, phototop);
}
if (bubble) { if (bubble) {
const HistoryMessageForwarded *fwd = Get<HistoryMessageForwarded>(); const HistoryMessageForwarded *fwd = Get<HistoryMessageForwarded>();
@ -6809,13 +6779,13 @@ void HistoryMessage::getState(TextLinkPtr &lnk, HistoryCursorState &state, int32
int left = 0, width = 0, height = _height; int left = 0, width = 0, height = _height;
countPositionAndSize(left, width); countPositionAndSize(left, width);
if (displayFromPhoto()) { //if (displayFromPhoto()) {
int32 photoleft = left + ((!isPost() && out() && !Adaptive::Wide()) ? (width + (st::msgPhotoSkip - st::msgPhotoSize)) : (-st::msgPhotoSkip)); // int32 photoleft = left + ((!isPost() && out() && !Adaptive::Wide()) ? (width + (st::msgPhotoSkip - st::msgPhotoSize)) : (-st::msgPhotoSkip));
if (x >= photoleft && x < photoleft + st::msgPhotoSize && y >= marginTop() && y < height - marginBottom()) { // if (x >= photoleft && x < photoleft + st::msgPhotoSize && y >= marginTop() && y < height - marginBottom()) {
lnk = author()->lnk; // lnk = author()->lnk;
return; // return;
} // }
} //}
if (width < 1) return; if (width < 1) return;
if (drawBubble()) { if (drawBubble()) {
@ -6972,6 +6942,14 @@ QString HistoryMessage::notificationText() const {
return msg; return msg;
} }
bool HistoryMessage::displayFromPhoto() const {
return hasFromPhoto() && !isAttachedToPrevious();
}
bool HistoryMessage::hasFromPhoto() const {
return (Adaptive::Wide() || (!out() && !history()->peer->isUser())) && !isPost();
}
HistoryMessage::~HistoryMessage() { HistoryMessage::~HistoryMessage() {
if (_media) { if (_media) {
_media->detachFromItem(this); _media->detachFromItem(this);
@ -7224,12 +7202,12 @@ void HistoryReply::getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x
if (drawBubble()) { if (drawBubble()) {
int32 left = 0, width = 0; int32 left = 0, width = 0;
countPositionAndSize(left, width); countPositionAndSize(left, width);
if (displayFromPhoto()) { //if (displayFromPhoto()) {
int32 photoleft = left + ((!isPost() && out()) ? (width + (st::msgPhotoSkip - st::msgPhotoSize)) : (-st::msgPhotoSkip)); // int32 photoleft = left + ((!isPost() && out()) ? (width + (st::msgPhotoSkip - st::msgPhotoSize)) : (-st::msgPhotoSkip));
if (x >= photoleft && x < photoleft + st::msgPhotoSize) { // if (x >= photoleft && x < photoleft + st::msgPhotoSize) {
return HistoryMessage::getState(lnk, state, x, y); // return HistoryMessage::getState(lnk, state, x, y);
} // }
} //}
if (width < 1) return; if (width < 1) return;
int top = marginTop(); int top = marginTop();

View File

@ -1384,6 +1384,9 @@ public:
int marginBottom() const { int marginBottom() const {
return st::msgMargin.bottom(); return st::msgMargin.bottom();
} }
bool isAttachedToPrevious() const {
return _flags & MTPDmessage_ClientFlag::f_attach_to_previous;
}
void clipCallback(ClipReaderNotification notification); void clipCallback(ClipReaderNotification notification);
@ -1434,14 +1437,6 @@ protected:
// HistoryMessageDate or HistoryMessageUnreadBar bit is changed in the Interfaces mask // HistoryMessageDate or HistoryMessageUnreadBar bit is changed in the Interfaces mask
// then the result should be cached in a client side flag MTPDmessage_ClientFlag::f_attach_to_previous // then the result should be cached in a client side flag MTPDmessage_ClientFlag::f_attach_to_previous
void recountAttachToPrevious(); void recountAttachToPrevious();
bool isAttachedToPrevious() const {
return _flags & MTPDmessage_ClientFlag::f_attach_to_previous;
}
// hasFromPhoto() returns true even if we don't display the photo
// but we need to skip a place at the left side for this photo
bool displayFromPhoto() const;
bool hasFromPhoto() const;
}; };
@ -2495,6 +2490,11 @@ public:
return this; return this;
} }
// hasFromPhoto() returns true even if we don't display the photo
// but we need to skip a place at the left side for this photo
bool displayFromPhoto() const;
bool hasFromPhoto() const;
~HistoryMessage(); ~HistoryMessage();
protected: protected:
@ -2519,13 +2519,14 @@ protected:
} }
void paintForwardedInfo(Painter &p, int32 x, int32 y, int32 w, bool selected) const; void paintForwardedInfo(Painter &p, int32 x, int32 y, int32 w, bool selected) const;
Text _text; Text _text = { st::msgMinWidth };
int32 _textWidth, _textHeight; int _textWidth = 0;
int _textHeight = 0;
HistoryMedia *_media; HistoryMedia *_media = nullptr;
QString _timeText; QString _timeText;
int32 _timeWidth; int _timeWidth = 0;
}; };

View File

@ -38,41 +38,13 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
// flick scroll taken from http://qt-project.org/doc/qt-4.8/demos-embedded-anomaly-src-flickcharm-cpp.html // flick scroll taken from http://qt-project.org/doc/qt-4.8/demos-embedded-anomaly-src-flickcharm-cpp.html
HistoryInner::HistoryInner(HistoryWidget *historyWidget, ScrollArea *scroll, History *history) : TWidget(0) HistoryInner::HistoryInner(HistoryWidget *historyWidget, ScrollArea *scroll, History *history) : TWidget(nullptr)
, _peer(history->peer) , _peer(history->peer)
, _migrated(history->peer->migrateFrom() ? App::history(history->peer->migrateFrom()->id) : 0) , _migrated(history->peer->migrateFrom() ? App::history(history->peer->migrateFrom()->id) : nullptr)
, _history(history) , _history(history)
, _historyOffset(0) , _botInfo(history->peer->isUser() ? history->peer->asUser()->botInfo : nullptr)
, _historySkipHeight(0)
, _botInfo(history->peer->isUser() ? history->peer->asUser()->botInfo : 0)
, _botDescWidth(0)
, _botDescHeight(0)
, _widget(historyWidget) , _widget(historyWidget)
, _scroll(scroll) , _scroll(scroll) {
, _curHistory(0)
, _curBlock(0)
, _curItem(0)
, _firstLoading(false)
, _cursor(style::cur_default)
, _dragAction(NoDrag)
, _dragSelType(TextSelectLetters)
, _dragItem(0)
, _dragCursorState(HistoryDefaultCursorState)
, _dragWasInactive(false)
, _dragSelFrom(0)
, _dragSelTo(0)
, _dragSelecting(false)
, _wasSelectedText(false)
, _touchScroll(false)
, _touchSelect(false)
, _touchInProgress(false)
, _touchScrollState(TouchScrollManual)
, _touchPrevPosValid(false)
, _touchWaitingAcceleration(false)
, _touchSpeedTime(0)
, _touchAccelerationTime(0)
, _touchTime(0)
, _menu(0) {
connect(App::wnd(), SIGNAL(imageLoaded()), this, SLOT(update())); connect(App::wnd(), SIGNAL(imageLoaded()), this, SLOT(update()));
_touchSelectTimer.setSingleShot(true); _touchSelectTimer.setSingleShot(true);
@ -122,6 +94,69 @@ void HistoryInner::repaintItem(const HistoryItem *item) {
} }
} }
template <typename Method>
void HistoryInner::enumerateUserpicsInHistory(History *h, int htop, Method method) {
// no displayed messages in this history
if (htop < 0) return;
// find and remember the bottom of an attached messages pack
// -1 means we didn't find an attached to previous message yet
int lowestAttachedItemBottom = -1;
int blockIndex = h->blocks.size();
int itemIndex = 0;
while (blockIndex > 0) {
HistoryBlock *block = h->blocks.at(--blockIndex);
itemIndex = block->items.size();
int blocktop = htop + block->y;
while (itemIndex > 0) {
HistoryItem *item = block->items.at(--itemIndex);
int itemtop = blocktop + item->y;
int itembottom = itemtop + item->height();
// skip items that are below the visible area
if (itemtop >= _visibleAreaBottom) {
continue;
}
if (HistoryMessage *message = item->toHistoryMessage()) {
if (lowestAttachedItemBottom < 0 && message->isAttachedToPrevious()) {
lowestAttachedItemBottom = itembottom - message->marginBottom();
}
// draw userpic for all messages that have it and for those who are not showing it
// because of their attachment to the previous message if they are top-most visible
if (message->displayFromPhoto() || (message->hasFromPhoto() && itemtop <= _visibleAreaTop)) {
if (lowestAttachedItemBottom < 0) {
lowestAttachedItemBottom = itembottom - message->marginBottom();
}
int userpicTop = qMin(qMax(itemtop + message->marginTop(), _visibleAreaTop + st::msgMargin.left()), lowestAttachedItemBottom - int(st::msgPhotoSize));
// call the template callback function that was passed
// and return if it finished everything it needed
if (!method(message, userpicTop)) {
return;
}
// forget the found bottom of the pack, search for the next one from scratch
lowestAttachedItemBottom = -1;
}
}
// skip all the items that are above the visible area
if (itemtop <= _visibleAreaTop) {
return;
}
}
// skip all the rest blocks that are above the visible area
if (blocktop <= _visibleAreaTop) {
return;
}
}
}
void HistoryInner::paintEvent(QPaintEvent *e) { void HistoryInner::paintEvent(QPaintEvent *e) {
if (App::wnd() && App::wnd()->contentOverlapped(this, e)) return; if (App::wnd() && App::wnd()->contentOverlapped(this, e)) return;
@ -252,6 +287,19 @@ void HistoryInner::paintEvent(QPaintEvent *e) {
item = block->items[iItem]; item = block->items[iItem];
} }
p.restore(); p.restore();
enumerateUserpics([&p, &r](HistoryMessage *message, int userpicTop) -> bool {
// stop the enumeration if the userpic is above the painted rect
if (userpicTop + st::msgPhotoSize <= r.top()) {
return false;
}
// paint the userpic if it intersects the painted rect
if (userpicTop < r.top() + r.height()) {
message->from()->paintUserpicLeft(p, st::msgPhotoSize, st::msgMargin.left(), userpicTop, message->history()->width);
}
return true;
});
} }
} }
} }
@ -1360,6 +1408,7 @@ HistoryItem *HistoryInner::atTopImportantMsg(int32 top, int32 height, int32 &bot
void HistoryInner::visibleAreaUpdated(int top, int bottom) { void HistoryInner::visibleAreaUpdated(int top, int bottom) {
_visibleAreaTop = top; _visibleAreaTop = top;
_visibleAreaBottom = bottom;
// if history has pending resize events we should not update scrollTopItem // if history has pending resize events we should not update scrollTopItem
if (_history->hasPendingResizedItems()) { if (_history->hasPendingResizedItems()) {
@ -1637,6 +1686,25 @@ void HistoryInner::onUpdateSelected() {
} }
} else if (item) { } else if (item) {
item->getState(lnk, cursorState, m.x(), m.y()); item->getState(lnk, cursorState, m.x(), m.y());
if (!lnk && m.x() >= st::msgMargin.left() && m.x() < st::msgMargin.left() + st::msgPhotoSize) {
if (HistoryMessage *msg = item->toHistoryMessage()) {
if (msg->hasFromPhoto()) {
enumerateUserpics([&lnk, msg, &point](HistoryMessage *message, int userpicTop) -> bool {
// stop enumeration if the userpic is above our point
if (userpicTop + st::msgPhotoSize <= point.y()) {
return false;
}
// stop enumeration if we've found a userpic under the cursor
if (point.y() >= userpicTop && point.y() < userpicTop + st::msgPhotoSize) {
lnk = message->from()->lnk;
return false;
}
return true;
});
}
}
}
} }
if (lnk != textlnkOver()) { if (lnk != textlnkOver()) {
lnkChanged = true; lnkChanged = true;
@ -2690,52 +2758,17 @@ QPoint SilentToggle::tooltipPos() const {
} }
HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent) HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent)
, _replyToId(0)
, _replyToNameVersion(0)
, _editMsgId(0)
, _replyEditMsg(0)
, _fieldBarCancel(this, st::replyCancel) , _fieldBarCancel(this, st::replyCancel)
, _pinnedBar(0)
, _saveEditMsgRequestId(0)
, _reportSpamStatus(dbiprsUnknown)
, _reportSpamSettingRequestId(ReportSpamRequestNeeded)
, _previewData(0)
, _previewRequest(0)
, _previewCancelled(false)
, _replyForwardPressed(false)
, _replyReturn(0)
, _stickersUpdateRequest(0)
, _savedGifsUpdateRequest(0)
, _peer(0)
, _clearPeer(0)
, _channel(NoChannel)
, _showAtMsgId(0)
, _fixedInScrollMsgId(0)
, _fixedInScrollMsgTop(0)
, _firstLoadRequest(0), _preloadRequest(0), _preloadDownRequest(0)
, _delayedShowAtMsgId(-1)
, _delayedShowAtRequest(0)
, _activeAnimMsgId(0)
, _scroll(this, st::historyScroll, false) , _scroll(this, st::historyScroll, false)
, _list(0)
, _migrated(0)
, _history(0)
, _histInited(false)
, _lastScroll(0)
, _lastScrolled(0)
, _toHistoryEnd(this, st::historyToEnd) , _toHistoryEnd(this, st::historyToEnd)
, _collapseComments(this) , _collapseComments(this)
, _attachMention(this) , _attachMention(this)
, _inlineBot(0)
, _inlineBotResolveRequestId(0)
, _reportSpamPanel(this) , _reportSpamPanel(this)
, _send(this, lang(lng_send_button), st::btnSend) , _send(this, lang(lng_send_button), st::btnSend)
, _unblock(this, lang(lng_unblock_button), st::btnUnblock) , _unblock(this, lang(lng_unblock_button), st::btnUnblock)
, _botStart(this, lang(lng_bot_start), st::btnSend) , _botStart(this, lang(lng_bot_start), st::btnSend)
, _joinChannel(this, lang(lng_channel_join), st::btnSend) , _joinChannel(this, lang(lng_channel_join), st::btnSend)
, _muteUnmute(this, lang(lng_channel_mute), st::btnSend) , _muteUnmute(this, lang(lng_channel_mute), st::btnSend)
, _unblockRequest(0)
, _reportSpamRequest(0)
, _attachDocument(this, st::btnAttachDocument) , _attachDocument(this, st::btnAttachDocument)
, _attachPhoto(this, st::btnAttachPhoto) , _attachPhoto(this, st::btnAttachPhoto)
, _attachEmoji(this, st::btnAttachEmoji) , _attachEmoji(this, st::btnAttachEmoji)
@ -2744,42 +2777,20 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent)
, _cmdStart(this, st::btnBotCmdStart) , _cmdStart(this, st::btnBotCmdStart)
, _broadcast(this, QString(), true, st::broadcastToggle) , _broadcast(this, QString(), true, st::broadcastToggle)
, _silent(this) , _silent(this)
, _cmdStartShown(false)
, _field(this, st::taMsgField, lang(lng_message_ph)) , _field(this, st::taMsgField, lang(lng_message_ph))
, _a_record(animation(this, &HistoryWidget::step_record)) , _a_record(animation(this, &HistoryWidget::step_record))
, _a_recording(animation(this, &HistoryWidget::step_recording)) , _a_recording(animation(this, &HistoryWidget::step_recording))
, _recording(false)
, _inRecord(false)
, _inField(false)
, _inReplyEdit(false)
, _inPinnedMsg(false)
, a_recordingLevel(0, 0)
, _recordingSamples(0)
, a_recordOver(0, 0)
, a_recordDown(0, 0)
, a_recordCancel(st::recordCancel->c, st::recordCancel->c) , a_recordCancel(st::recordCancel->c, st::recordCancel->c)
, _recordCancelWidth(st::recordFont->width(lang(lng_record_cancel))) , _recordCancelWidth(st::recordFont->width(lang(lng_record_cancel)))
, _kbShown(false)
, _kbReplyTo(0)
, _kbScroll(this, st::botKbScroll) , _kbScroll(this, st::botKbScroll)
, _keyboard()
, _attachType(this) , _attachType(this)
, _emojiPan(this) , _emojiPan(this)
, _attachDrag(DragStateNone)
, _attachDragDocument(this) , _attachDragDocument(this)
, _attachDragPhoto(this) , _attachDragPhoto(this)
, _fileLoader(this, FileLoaderQueueStopTimeout) , _fileLoader(this, FileLoaderQueueStopTimeout)
, _textUpdateEventsFlags(TextUpdateEventsSaveDraft | TextUpdateEventsSendTyping)
, _serviceImageCacheSize(0)
, _confirmWithTextId(0)
, _titlePeerTextWidth(0)
, _a_show(animation(this, &HistoryWidget::step_show)) , _a_show(animation(this, &HistoryWidget::step_show))
, _scrollDelta(0)
, _saveDraftStart(0)
, _saveDraftText(false)
, _sideShadow(this, st::shadowColor) , _sideShadow(this, st::shadowColor)
, _topShadow(this, st::shadowColor) , _topShadow(this, st::shadowColor) {
, _inGrab(false) {
_scroll.setFocusPolicy(Qt::NoFocus); _scroll.setFocusPolicy(Qt::NoFocus);
setAcceptDrops(true); setAcceptDrops(true);
@ -3658,7 +3669,7 @@ void HistoryWidget::showHistory(const PeerId &peerId, MsgId showAtMsgId, bool re
_fieldBarCancel.hide(); _fieldBarCancel.hide();
if (_list) _list->deleteLater(); if (_list) _list->deleteLater();
_list = 0; _list = nullptr;
_scroll.takeWidget(); _scroll.takeWidget();
updateTopBarSelection(); updateTopBarSelection();
@ -3730,6 +3741,7 @@ void HistoryWidget::showHistory(const PeerId &peerId, MsgId showAtMsgId, bool re
_scroll.hide(); _scroll.hide();
_scroll.setWidget(_list); _scroll.setWidget(_list);
_list->show(); _list->show();
visibleAreaUpdated();
_updateHistoryItems.stop(); _updateHistoryItems.stop();
@ -3965,9 +3977,9 @@ void HistoryWidget::updateControlsVisibility() {
_pinnedBar->cancel.show(); _pinnedBar->cancel.show();
_pinnedBar->shadow.show(); _pinnedBar->shadow.show();
} }
if (_firstLoadRequest) { if (_firstLoadRequest && !_scroll.isHidden()) {
_scroll.hide(); _scroll.hide();
} else { } else if (!_firstLoadRequest && _scroll.isHidden()) {
_scroll.show(); _scroll.show();
} }
if (_reportSpamStatus == dbiprsShowButton || _reportSpamStatus == dbiprsReportSent) { if (_reportSpamStatus == dbiprsShowButton || _reportSpamStatus == dbiprsReportSent) {
@ -4578,7 +4590,10 @@ void HistoryWidget::delayedShowAt(MsgId showAtMsgId) {
void HistoryWidget::onScroll() { void HistoryWidget::onScroll() {
App::checkImageCacheSize(); App::checkImageCacheSize();
preloadHistoryIfNeeded(); preloadHistoryIfNeeded();
visibleAreaUpdated();
}
void HistoryWidget::visibleAreaUpdated() {
if (_list && !_scroll.isHidden()) { if (_list && !_scroll.isHidden()) {
int st = _scroll.scrollTop(); int st = _scroll.scrollTop();
_list->visibleAreaUpdated(st, st + _scroll.height()); _list->visibleAreaUpdated(st, st + _scroll.height());
@ -6385,6 +6400,8 @@ void HistoryWidget::updateListSize(bool initial, bool loadedDown, const ScrollCh
bool wasAtBottom = _scroll.scrollTop() + 1 > _scroll.scrollTopMax(), needResize = _scroll.width() != width() || _scroll.height() != newScrollHeight; bool wasAtBottom = _scroll.scrollTop() + 1 > _scroll.scrollTopMax(), needResize = _scroll.width() != width() || _scroll.height() != newScrollHeight;
if (needResize) { if (needResize) {
_scroll.resize(width(), newScrollHeight); _scroll.resize(width(), newScrollHeight);
visibleAreaUpdated();
_attachMention.setBoundings(_scroll.geometry()); _attachMention.setBoundings(_scroll.geometry());
_toHistoryEnd.move((width() - _toHistoryEnd.width()) / 2, _scroll.y() + _scroll.height() - _toHistoryEnd.height() - st::historyToEndSkip); _toHistoryEnd.move((width() - _toHistoryEnd.width()) / 2, _scroll.y() + _scroll.height() - _toHistoryEnd.height() - st::historyToEndSkip);
updateCollapseCommentsVisibility(); updateCollapseCommentsVisibility();
@ -6402,13 +6419,19 @@ void HistoryWidget::updateListSize(bool initial, bool loadedDown, const ScrollCh
} }
if ((!initial && !wasAtBottom) || (loadedDown && (!_history->showFrom || _history->unreadBar || _history->loadedAtBottom()) && (!_migrated || !_migrated->showFrom || _migrated->unreadBar || _history->loadedAtBottom()))) { if ((!initial && !wasAtBottom) || (loadedDown && (!_history->showFrom || _history->unreadBar || _history->loadedAtBottom()) && (!_migrated || !_migrated->showFrom || _migrated->unreadBar || _history->loadedAtBottom()))) {
int32 addToY = 0; int addToY = 0;
if (change.type == ScrollChangeAdd) { if (change.type == ScrollChangeAdd) {
addToY = change.value; addToY = change.value;
} else if (change.type == ScrollChangeOldHistoryHeight) { } else if (change.type == ScrollChangeOldHistoryHeight) {
addToY = _list->historyHeight() - change.value; addToY = _list->historyHeight() - change.value;
} }
_scroll.scrollToY(_list->historyScrollTop() + addToY); int toY = _list->historyScrollTop() + addToY;
if (toY > _scroll.scrollTopMax()) toY = _scroll.scrollTopMax();
if (_scroll.scrollTop() == toY) {
visibleAreaUpdated();
} else {
_scroll.scrollToY(toY);
}
return; return;
} }
@ -6511,7 +6534,12 @@ void HistoryWidget::updateListSize(bool initial, bool loadedDown, const ScrollCh
} }
} else { } else {
} }
_scroll.scrollToY(toY); if (toY > _scroll.scrollTopMax()) toY = _scroll.scrollTopMax();
if (_scroll.scrollTop() == toY) {
visibleAreaUpdated();
} else {
_scroll.scrollToY(toY);
}
} }
void HistoryWidget::addMessagesToFront(PeerData *peer, const QVector<MTPMessage> &messages, const QVector<MTPMessageGroup> *collapsed) { void HistoryWidget::addMessagesToFront(PeerData *peer, const QVector<MTPMessage> &messages, const QVector<MTPMessageGroup> *collapsed) {

View File

@ -139,22 +139,30 @@ private:
HistoryItem *nextItem(HistoryItem *item); HistoryItem *nextItem(HistoryItem *item);
void updateDragSelection(HistoryItem *dragSelFrom, HistoryItem *dragSelTo, bool dragSelecting, bool force = false); void updateDragSelection(HistoryItem *dragSelFrom, HistoryItem *dragSelTo, bool dragSelecting, bool force = false);
PeerData *_peer; PeerData *_peer = nullptr;
History *_migrated, *_history; History *_migrated = nullptr;
int32 _historyOffset, _historySkipHeight; // height of first date and first sys msg History *_history = nullptr;
int _historyOffset = 0;
BotInfo *_botInfo; // with migrated history we perhaps do not need to display first _history message
int32 _botDescWidth, _botDescHeight; // (if last _migrated message and first _history message are both isGroupMigrate)
// or at least we don't need to display first _history date (just skip it by height)
int _historySkipHeight = 0;
BotInfo *_botInfo = nullptr;
int _botDescWidth = 0;
int _botDescHeight = 0;
QRect _botDescRect; QRect _botDescRect;
HistoryWidget *_widget; HistoryWidget *_widget = nullptr;
ScrollArea *_scroll; ScrollArea *_scroll = nullptr;
mutable History *_curHistory; mutable History *_curHistory = nullptr;
mutable int32 _curBlock, _curItem; mutable int _curBlock = 0;
mutable int _curItem = 0;
bool _firstLoading; bool _firstLoading = false;
Qt::CursorShape _cursor; style::cursor _cursor = style::cur_default;
typedef QMap<HistoryItem*, uint32> SelectedItems; typedef QMap<HistoryItem*, uint32> SelectedItems;
SelectedItems _selected; SelectedItems _selected;
void applyDragSelection(); void applyDragSelection();
@ -168,36 +176,60 @@ private:
PrepareSelect = 0x03, PrepareSelect = 0x03,
Selecting = 0x04, Selecting = 0x04,
}; };
DragAction _dragAction; DragAction _dragAction = NoDrag;
TextSelectType _dragSelType; TextSelectType _dragSelType = TextSelectLetters;
QPoint _dragStartPos, _dragPos; QPoint _dragStartPos, _dragPos;
HistoryItem *_dragItem; HistoryItem *_dragItem = nullptr;
HistoryCursorState _dragCursorState; HistoryCursorState _dragCursorState = HistoryDefaultCursorState;
uint16 _dragSymbol; uint16 _dragSymbol = 0;
bool _dragWasInactive; bool _dragWasInactive = false;
QPoint _trippleClickPoint; QPoint _trippleClickPoint;
QTimer _trippleClickTimer; QTimer _trippleClickTimer;
TextLinkPtr _contextMenuLnk; TextLinkPtr _contextMenuLnk;
HistoryItem *_dragSelFrom, *_dragSelTo; HistoryItem *_dragSelFrom = nullptr;
bool _dragSelecting; HistoryItem *_dragSelTo = nullptr;
bool _wasSelectedText; // was some text selected in current drag action bool _dragSelecting = false;
bool _wasSelectedText = false; // was some text selected in current drag action
bool _touchScroll, _touchSelect, _touchInProgress; // scroll by touch support (at least Windows Surface tablets)
bool _touchScroll = false;
bool _touchSelect = false;
bool _touchInProgress = false;
QPoint _touchStart, _touchPrevPos, _touchPos; QPoint _touchStart, _touchPrevPos, _touchPos;
QTimer _touchSelectTimer; QTimer _touchSelectTimer;
TouchScrollState _touchScrollState; TouchScrollState _touchScrollState = TouchScrollManual;
bool _touchPrevPosValid, _touchWaitingAcceleration; bool _touchPrevPosValid = false;
bool _touchWaitingAcceleration = false;
QPoint _touchSpeed; QPoint _touchSpeed;
uint64 _touchSpeedTime, _touchAccelerationTime, _touchTime; uint64 _touchSpeedTime = 0;
uint64 _touchAccelerationTime = 0;
uint64 _touchTime = 0;
QTimer _touchScrollTimer; QTimer _touchScrollTimer;
PopupMenu *_menu; // context menu
PopupMenu *_menu = nullptr;
// save visible area coords for painting / pressing userpics
int _visibleAreaTop = 0; int _visibleAreaTop = 0;
int _visibleAreaBottom = 0;
// this function finds all userpics on the left that are displayed and calls template method
// for each found userpic (from the bottom to the top) in the passed history with passed top offset
//
// method has "bool (*Method)(HistoryMessage *message, int userpicTop)" signature
// if it returns false the enumeration stops immidiately
template <typename Method>
void enumerateUserpicsInHistory(History *h, int htop, Method method);
template <typename Method>
void enumerateUserpics(Method method) {
enumerateUserpicsInHistory(_history, historyTop(), method);
enumerateUserpicsInHistory(_migrated, migratedTop(), method);
}
}; };
@ -721,14 +753,14 @@ public slots:
private: private:
MsgId _replyToId; MsgId _replyToId = 0;
Text _replyToName; Text _replyToName;
int32 _replyToNameVersion; int _replyToNameVersion = 0;
void updateReplyToName(); void updateReplyToName();
MsgId _editMsgId; MsgId _editMsgId = 0;
HistoryItem *_replyEditMsg; HistoryItem *_replyEditMsg = nullptr;
Text _replyEditMsgText; Text _replyEditMsgText;
IconedButton _fieldBarCancel; IconedButton _fieldBarCancel;
@ -737,13 +769,13 @@ private:
struct PinnedBar { struct PinnedBar {
PinnedBar(MsgId msgId, HistoryWidget *parent); PinnedBar(MsgId msgId, HistoryWidget *parent);
MsgId msgId; MsgId msgId = 0;
HistoryItem *msg; HistoryItem *msg = nullptr;
Text text; Text text;
IconedButton cancel; IconedButton cancel;
PlainShadow shadow; PlainShadow shadow;
}; };
PinnedBar *_pinnedBar; PinnedBar *_pinnedBar = nullptr;
void updatePinnedBar(bool force = false); void updatePinnedBar(bool force = false);
bool pinnedMsgVisibilityUpdated(); bool pinnedMsgVisibilityUpdated();
void destroyPinnedBar(); void destroyPinnedBar();
@ -767,32 +799,33 @@ private:
// destroys _history and _migrated unread bars // destroys _history and _migrated unread bars
void destroyUnreadBar(); void destroyUnreadBar();
mtpRequestId _saveEditMsgRequestId; mtpRequestId _saveEditMsgRequestId = 0;
void saveEditMsg(); void saveEditMsg();
void saveEditMsgDone(History *history, const MTPUpdates &updates, mtpRequestId req); void saveEditMsgDone(History *history, const MTPUpdates &updates, mtpRequestId req);
bool saveEditMsgFail(History *history, const RPCError &error, mtpRequestId req); bool saveEditMsgFail(History *history, const RPCError &error, mtpRequestId req);
DBIPeerReportSpamStatus _reportSpamStatus;
mtpRequestId _reportSpamSettingRequestId;
static const mtpRequestId ReportSpamRequestNeeded = -1; static const mtpRequestId ReportSpamRequestNeeded = -1;
DBIPeerReportSpamStatus _reportSpamStatus = dbiprsUnknown;
mtpRequestId _reportSpamSettingRequestId = ReportSpamRequestNeeded;
void updateReportSpamStatus(); void updateReportSpamStatus();
void requestReportSpamSetting(); void requestReportSpamSetting();
void reportSpamSettingDone(const MTPPeerSettings &result, mtpRequestId req); void reportSpamSettingDone(const MTPPeerSettings &result, mtpRequestId req);
bool reportSpamSettingFail(const RPCError &error, mtpRequestId req); bool reportSpamSettingFail(const RPCError &error, mtpRequestId req);
QString _previewLinks; QString _previewLinks;
WebPageData *_previewData; WebPageData *_previewData = nullptr;
typedef QMap<QString, WebPageId> PreviewCache; typedef QMap<QString, WebPageId> PreviewCache;
PreviewCache _previewCache; PreviewCache _previewCache;
mtpRequestId _previewRequest; mtpRequestId _previewRequest = 0;
Text _previewTitle, _previewDescription; Text _previewTitle;
Text _previewDescription;
SingleTimer _previewTimer; SingleTimer _previewTimer;
bool _previewCancelled; bool _previewCancelled = false;
void gotPreview(QString links, const MTPMessageMedia &media, mtpRequestId req); void gotPreview(QString links, const MTPMessageMedia &media, mtpRequestId req);
bool _replyForwardPressed; bool _replyForwardPressed = false;
HistoryItem *_replyReturn; HistoryItem *_replyReturn = nullptr;
QList<MsgId> _replyReturns; QList<MsgId> _replyReturns;
bool messagesFailed(const RPCError &error, mtpRequestId requestId); bool messagesFailed(const RPCError &error, mtpRequestId requestId);
@ -824,11 +857,11 @@ private:
void countHistoryShowFrom(); void countHistoryShowFrom();
mtpRequestId _stickersUpdateRequest; mtpRequestId _stickersUpdateRequest = 0;
void stickersGot(const MTPmessages_AllStickers &stickers); void stickersGot(const MTPmessages_AllStickers &stickers);
bool stickersFailed(const RPCError &error); bool stickersFailed(const RPCError &error);
mtpRequestId _savedGifsUpdateRequest; mtpRequestId _savedGifsUpdateRequest = 0;
void savedGifsGot(const MTPmessages_SavedGifs &gifs); void savedGifsGot(const MTPmessages_SavedGifs &gifs);
bool savedGifsFailed(const RPCError &error); bool savedGifsFailed(const RPCError &error);
@ -840,39 +873,51 @@ private:
void updateDragAreas(); void updateDragAreas();
// when scroll position or scroll area size changed this method
// updates the boundings of the visible area in HistoryInner
void visibleAreaUpdated();
bool readyToForward() const; bool readyToForward() const;
bool hasBroadcastToggle() const; bool hasBroadcastToggle() const;
bool hasSilentToggle() const; bool hasSilentToggle() const;
PeerData *_peer, *_clearPeer; // cache _peer in _clearPeer when showing clear history box PeerData *_peer = nullptr;
ChannelId _channel;
bool _canSendMessages;
MsgId _showAtMsgId, _fixedInScrollMsgId;
int32 _fixedInScrollMsgTop;
mtpRequestId _firstLoadRequest, _preloadRequest, _preloadDownRequest; // cache current _peer in _clearPeer when showing clear history box
PeerData *_clearPeer = nullptr;
MsgId _delayedShowAtMsgId; ChannelId _channel = NoChannel;
mtpRequestId _delayedShowAtRequest; bool _canSendMessages = false;
MsgId _showAtMsgId = ShowAtUnreadMsgId;
MsgId _fixedInScrollMsgId = 0;
int32 _fixedInScrollMsgTop = 0;
MsgId _activeAnimMsgId; mtpRequestId _firstLoadRequest = 0;
mtpRequestId _preloadRequest = 0;
mtpRequestId _preloadDownRequest = 0;
MsgId _delayedShowAtMsgId = -1; // wtf?
mtpRequestId _delayedShowAtRequest = 0;
MsgId _activeAnimMsgId = 0;
ScrollArea _scroll; ScrollArea _scroll;
HistoryInner *_list; HistoryInner *_list = nullptr;
History *_migrated, *_history; History *_migrated = nullptr;
bool _histInited; // initial updateListSize() called History *_history = nullptr;
bool _histInited = false; // initial updateListSize() called
int32 _lastScroll; int32 _lastScroll = 0;
uint64 _lastScrolled; uint64 _lastScrolled = 0;
QTimer _updateHistoryItems; // gifs optimization QTimer _updateHistoryItems; // gifs optimization
IconedButton _toHistoryEnd; IconedButton _toHistoryEnd;
CollapseButton _collapseComments; CollapseButton _collapseComments;
MentionsDropdown _attachMention; MentionsDropdown _attachMention;
UserData *_inlineBot; UserData *_inlineBot = nullptr;
QString _inlineBotUsername; QString _inlineBotUsername;
mtpRequestId _inlineBotResolveRequestId; mtpRequestId _inlineBotResolveRequestId = 0;
void inlineBotResolveDone(const MTPcontacts_ResolvedPeer &result); void inlineBotResolveDone(const MTPcontacts_ResolvedPeer &result);
bool inlineBotResolveFail(QString name, const RPCError &error); bool inlineBotResolveFail(QString name, const RPCError &error);
@ -885,46 +930,52 @@ private:
ReportSpamPanel _reportSpamPanel; ReportSpamPanel _reportSpamPanel;
FlatButton _send, _unblock, _botStart, _joinChannel, _muteUnmute; FlatButton _send, _unblock, _botStart, _joinChannel, _muteUnmute;
mtpRequestId _unblockRequest, _reportSpamRequest; mtpRequestId _unblockRequest = 0;
mtpRequestId _reportSpamRequest = 0;
IconedButton _attachDocument, _attachPhoto; IconedButton _attachDocument, _attachPhoto;
EmojiButton _attachEmoji; EmojiButton _attachEmoji;
IconedButton _kbShow, _kbHide, _cmdStart; IconedButton _kbShow, _kbHide, _cmdStart;
FlatCheckbox _broadcast; FlatCheckbox _broadcast;
SilentToggle _silent; SilentToggle _silent;
bool _cmdStartShown; bool _cmdStartShown = false;
MessageField _field; MessageField _field;
Animation _a_record, _a_recording; Animation _a_record, _a_recording;
bool _recording, _inRecord, _inField, _inReplyEdit, _inPinnedMsg; bool _recording = false;
anim::ivalue a_recordingLevel; bool _inRecord = false;
int32 _recordingSamples; bool _inField = false;
anim::fvalue a_recordOver, a_recordDown; bool _inReplyEdit = false;
bool _inPinnedMsg = false;
anim::ivalue a_recordingLevel = { 0, 0 };
int32 _recordingSamples = 0;
anim::fvalue a_recordOver = { 0, 0 };
anim::fvalue a_recordDown = { 0, 0 };
anim::cvalue a_recordCancel; anim::cvalue a_recordCancel;
int32 _recordCancelWidth; int32 _recordCancelWidth;
bool kbWasHidden() const; bool kbWasHidden() const;
bool _kbShown; bool _kbShown = false;
HistoryItem *_kbReplyTo; HistoryItem *_kbReplyTo = nullptr;
ScrollArea _kbScroll; ScrollArea _kbScroll;
BotKeyboard _keyboard; BotKeyboard _keyboard;
Dropdown _attachType; Dropdown _attachType;
EmojiPan _emojiPan; EmojiPan _emojiPan;
DragState _attachDrag; DragState _attachDrag = DragStateNone;
DragArea _attachDragDocument, _attachDragPhoto; DragArea _attachDragDocument, _attachDragPhoto;
int32 _selCount; // < 0 - text selected, focus list, not _field int32 _selCount; // < 0 - text selected, focus list, not _field
TaskQueue _fileLoader; TaskQueue _fileLoader;
int32 _textUpdateEventsFlags; int32 _textUpdateEventsFlags = (TextUpdateEventsSaveDraft | TextUpdateEventsSendTyping);
int64 _serviceImageCacheSize; int64 _serviceImageCacheSize = 0;
QString _confirmSource; QString _confirmSource;
uint64 _confirmWithTextId; uint64 _confirmWithTextId = 0;
QString _titlePeerText; QString _titlePeerText;
int32 _titlePeerTextWidth; int32 _titlePeerTextWidth = 0;
Animation _a_show; Animation _a_show;
QPixmap _cacheUnder, _cacheOver, _cacheTopBarUnder, _cacheTopBarOver; QPixmap _cacheUnder, _cacheOver, _cacheTopBarUnder, _cacheTopBarOver;
@ -932,20 +983,20 @@ private:
anim::fvalue a_shadow; anim::fvalue a_shadow;
QTimer _scrollTimer; QTimer _scrollTimer;
int32 _scrollDelta; int32 _scrollDelta = 0;
QTimer _animActiveTimer; QTimer _animActiveTimer;
float64 _animActiveStart; float64 _animActiveStart = 0;
QMap<QPair<History*, SendActionType>, mtpRequestId> _sendActionRequests; QMap<QPair<History*, SendActionType>, mtpRequestId> _sendActionRequests;
QTimer _sendActionStopTimer; QTimer _sendActionStopTimer;
uint64 _saveDraftStart; uint64 _saveDraftStart = 0;
bool _saveDraftText; bool _saveDraftText = false;
QTimer _saveDraftTimer; QTimer _saveDraftTimer;
PlainShadow _sideShadow, _topShadow; PlainShadow _sideShadow, _topShadow;
bool _inGrab; bool _inGrab = false;
}; };

View File

@ -34,8 +34,8 @@ IDI_ICON1 ICON "SourceFiles\\art\\icon256.ico"
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 0,9,34,1 FILEVERSION 0,9,34,2
PRODUCTVERSION 0,9,34,1 PRODUCTVERSION 0,9,34,2
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -51,10 +51,10 @@ BEGIN
BLOCK "040904b0" BLOCK "040904b0"
BEGIN BEGIN
VALUE "CompanyName", "Telegram Messenger LLP" VALUE "CompanyName", "Telegram Messenger LLP"
VALUE "FileVersion", "0.9.34.1" VALUE "FileVersion", "0.9.34.2"
VALUE "LegalCopyright", "Copyright (C) 2014-2016" VALUE "LegalCopyright", "Copyright (C) 2014-2016"
VALUE "ProductName", "Telegram Desktop" VALUE "ProductName", "Telegram Desktop"
VALUE "ProductVersion", "0.9.34.1" VALUE "ProductVersion", "0.9.34.2"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

View File

@ -3,4 +3,4 @@ AppVersionStrMajor 0.9
AppVersionStrSmall 0.9.34 AppVersionStrSmall 0.9.34
AppVersionStr 0.9.34 AppVersionStr 0.9.34
DevChannel 0 DevChannel 0
BetaVersion 9034001 BetaVersion 9034002