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 wchar_t *AppVersionStr = L"0.9.34";
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 *AppName = L"Telegram Desktop";
@ -101,8 +101,8 @@ enum {
MediaOverviewStartPerPage = 5,
MediaOverviewPreloadCount = 4,
// a new message from the same sender is attached to previous within 30 seconds
AttachMessageToPreviousSecondsDelta = 30,
// a new message from the same sender is attached to previous within 15 minutes
AttachMessageToPreviousSecondsDelta = 900,
AudioVoiceMsgSimultaneously = 4,
AudioSongSimultaneously = 4,

View File

@ -2843,7 +2843,7 @@ void HistoryItem::recountAttachToPrevious() {
bool attach = false;
if (!isPost() && !Is<HistoryMessageDate>() && !Is<HistoryMessageUnreadBar>()) {
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)) {
@ -2860,14 +2860,6 @@ void HistoryItem::setId(MsgId 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 {
ChannelData *channel = _history->peer->asChannel();
int32 s = date.secsTo(cur);
@ -6039,10 +6031,7 @@ void HistoryMessageForwarded::create(const HistoryMessageVia *via) const {
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)
, _text(st::msgMinWidth)
, _textWidth(0)
, _textHeight(0)
, _media(0) {
, _text(st::msgMinWidth) {
PeerId authorOriginalId = 0, fromOriginalId = 0;
MsgId originalId = 0;
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)
: HistoryItem(history, id, newForwardedFlags(history->peer, from, fwd) | flags, date, from)
, _text(st::msgMinWidth)
, _textWidth(0)
, _textHeight(0)
, _media(nullptr) {
: HistoryItem(history, id, newForwardedFlags(history->peer, from, fwd) | flags, date, from) {
UserData *fwdViaBot = fwd->viaBot();
int32 viaBotId = fwdViaBot ? peerToUser(fwdViaBot->id) : 0;
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)
: HistoryItem(history, id, flags, date, (flags & MTPDmessage::Flag::f_from_id) ? from : 0)
, _text(st::msgMinWidth)
, _textWidth(0)
, _textHeight(0)
, _media(nullptr) {
: HistoryItem(history, id, flags, date, (flags & MTPDmessage::Flag::f_from_id) ? from : 0) {
createInterfaces((flags & MTPDmessage::Flag::f_via_bot_id) ? viaBotId : 0, isPost() ? 1 : -1);
setText(msg, entities);
}
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)
, _text(st::msgMinWidth)
, _textWidth(0)
, _textHeight(0)
, _media(nullptr) {
HistoryItem(history, msgId, flags, date, (flags & MTPDmessage::Flag::f_from_id) ? from : 0) {
createInterfaces((flags & MTPDmessage::Flag::f_via_bot_id) ? viaBotId : 0, isPost() ? 1 : -1);
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) :
HistoryItem(history, msgId, flags, date, (flags & MTPDmessage::Flag::f_from_id) ? from : 0)
, _text(st::msgMinWidth)
, _textWidth(0)
, _textHeight(0)
, _media(nullptr) {
HistoryItem(history, msgId, flags, date, (flags & MTPDmessage::Flag::f_from_id) ? from : 0) {
createInterfaces((flags & MTPDmessage::Flag::f_via_bot_id) ? viaBotId : 0, isPost() ? 1 : -1);
_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));
if (displayFromPhoto()) {
int photoleft = left + ((outbg && !Adaptive::Wide()) ? (width + (st::msgPhotoSkip - st::msgPhotoSize)) : (-st::msgPhotoSkip));
int phototop = marginTop();
// if (history()->scrollTopItem == this) {
// phototop = qMax(qMin(history()->scrollTopOffset, _height - marginBottom() - int(st::msgPhotoSize)), phototop);
// }
author()->paintUserpic(p, st::msgPhotoSize, photoleft, phototop);
}
//if (displayFromPhoto()) {
// int photoleft = left + ((outbg && !Adaptive::Wide()) ? (width + (st::msgPhotoSkip - st::msgPhotoSize)) : (-st::msgPhotoSkip));
// int phototop = marginTop();
// author()->paintUserpic(p, st::msgPhotoSize, photoleft, phototop);
//}
if (bubble) {
const HistoryMessageForwarded *fwd = Get<HistoryMessageForwarded>();
@ -6809,13 +6779,13 @@ void HistoryMessage::getState(TextLinkPtr &lnk, HistoryCursorState &state, int32
int left = 0, width = 0, height = _height;
countPositionAndSize(left, width);
if (displayFromPhoto()) {
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()) {
lnk = author()->lnk;
return;
}
}
//if (displayFromPhoto()) {
// 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()) {
// lnk = author()->lnk;
// return;
// }
//}
if (width < 1) return;
if (drawBubble()) {
@ -6972,6 +6942,14 @@ QString HistoryMessage::notificationText() const {
return msg;
}
bool HistoryMessage::displayFromPhoto() const {
return hasFromPhoto() && !isAttachedToPrevious();
}
bool HistoryMessage::hasFromPhoto() const {
return (Adaptive::Wide() || (!out() && !history()->peer->isUser())) && !isPost();
}
HistoryMessage::~HistoryMessage() {
if (_media) {
_media->detachFromItem(this);
@ -7224,12 +7202,12 @@ void HistoryReply::getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x
if (drawBubble()) {
int32 left = 0, width = 0;
countPositionAndSize(left, width);
if (displayFromPhoto()) {
int32 photoleft = left + ((!isPost() && out()) ? (width + (st::msgPhotoSkip - st::msgPhotoSize)) : (-st::msgPhotoSkip));
if (x >= photoleft && x < photoleft + st::msgPhotoSize) {
return HistoryMessage::getState(lnk, state, x, y);
}
}
//if (displayFromPhoto()) {
// int32 photoleft = left + ((!isPost() && out()) ? (width + (st::msgPhotoSkip - st::msgPhotoSize)) : (-st::msgPhotoSkip));
// if (x >= photoleft && x < photoleft + st::msgPhotoSize) {
// return HistoryMessage::getState(lnk, state, x, y);
// }
//}
if (width < 1) return;
int top = marginTop();

View File

@ -1384,6 +1384,9 @@ public:
int marginBottom() const {
return st::msgMargin.bottom();
}
bool isAttachedToPrevious() const {
return _flags & MTPDmessage_ClientFlag::f_attach_to_previous;
}
void clipCallback(ClipReaderNotification notification);
@ -1434,14 +1437,6 @@ protected:
// 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
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;
}
// 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();
protected:
@ -2519,13 +2519,14 @@ protected:
}
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;
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
HistoryInner::HistoryInner(HistoryWidget *historyWidget, ScrollArea *scroll, History *history) : TWidget(0)
HistoryInner::HistoryInner(HistoryWidget *historyWidget, ScrollArea *scroll, History *history) : TWidget(nullptr)
, _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)
, _historyOffset(0)
, _historySkipHeight(0)
, _botInfo(history->peer->isUser() ? history->peer->asUser()->botInfo : 0)
, _botDescWidth(0)
, _botDescHeight(0)
, _botInfo(history->peer->isUser() ? history->peer->asUser()->botInfo : nullptr)
, _widget(historyWidget)
, _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) {
, _scroll(scroll) {
connect(App::wnd(), SIGNAL(imageLoaded()), this, SLOT(update()));
_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) {
if (App::wnd() && App::wnd()->contentOverlapped(this, e)) return;
@ -252,6 +287,19 @@ void HistoryInner::paintEvent(QPaintEvent *e) {
item = block->items[iItem];
}
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) {
_visibleAreaTop = top;
_visibleAreaBottom = bottom;
// if history has pending resize events we should not update scrollTopItem
if (_history->hasPendingResizedItems()) {
@ -1637,6 +1686,25 @@ void HistoryInner::onUpdateSelected() {
}
} else if (item) {
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()) {
lnkChanged = true;
@ -2690,52 +2758,17 @@ QPoint SilentToggle::tooltipPos() const {
}
HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent)
, _replyToId(0)
, _replyToNameVersion(0)
, _editMsgId(0)
, _replyEditMsg(0)
, _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)
, _list(0)
, _migrated(0)
, _history(0)
, _histInited(false)
, _lastScroll(0)
, _lastScrolled(0)
, _toHistoryEnd(this, st::historyToEnd)
, _collapseComments(this)
, _attachMention(this)
, _inlineBot(0)
, _inlineBotResolveRequestId(0)
, _reportSpamPanel(this)
, _send(this, lang(lng_send_button), st::btnSend)
, _unblock(this, lang(lng_unblock_button), st::btnUnblock)
, _botStart(this, lang(lng_bot_start), st::btnSend)
, _joinChannel(this, lang(lng_channel_join), st::btnSend)
, _muteUnmute(this, lang(lng_channel_mute), st::btnSend)
, _unblockRequest(0)
, _reportSpamRequest(0)
, _attachDocument(this, st::btnAttachDocument)
, _attachPhoto(this, st::btnAttachPhoto)
, _attachEmoji(this, st::btnAttachEmoji)
@ -2744,42 +2777,20 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent)
, _cmdStart(this, st::btnBotCmdStart)
, _broadcast(this, QString(), true, st::broadcastToggle)
, _silent(this)
, _cmdStartShown(false)
, _field(this, st::taMsgField, lang(lng_message_ph))
, _a_record(animation(this, &HistoryWidget::step_record))
, _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)
, _recordCancelWidth(st::recordFont->width(lang(lng_record_cancel)))
, _kbShown(false)
, _kbReplyTo(0)
, _kbScroll(this, st::botKbScroll)
, _keyboard()
, _attachType(this)
, _emojiPan(this)
, _attachDrag(DragStateNone)
, _attachDragDocument(this)
, _attachDragPhoto(this)
, _fileLoader(this, FileLoaderQueueStopTimeout)
, _textUpdateEventsFlags(TextUpdateEventsSaveDraft | TextUpdateEventsSendTyping)
, _serviceImageCacheSize(0)
, _confirmWithTextId(0)
, _titlePeerTextWidth(0)
, _a_show(animation(this, &HistoryWidget::step_show))
, _scrollDelta(0)
, _saveDraftStart(0)
, _saveDraftText(false)
, _sideShadow(this, st::shadowColor)
, _topShadow(this, st::shadowColor)
, _inGrab(false) {
, _topShadow(this, st::shadowColor) {
_scroll.setFocusPolicy(Qt::NoFocus);
setAcceptDrops(true);
@ -3658,7 +3669,7 @@ void HistoryWidget::showHistory(const PeerId &peerId, MsgId showAtMsgId, bool re
_fieldBarCancel.hide();
if (_list) _list->deleteLater();
_list = 0;
_list = nullptr;
_scroll.takeWidget();
updateTopBarSelection();
@ -3730,6 +3741,7 @@ void HistoryWidget::showHistory(const PeerId &peerId, MsgId showAtMsgId, bool re
_scroll.hide();
_scroll.setWidget(_list);
_list->show();
visibleAreaUpdated();
_updateHistoryItems.stop();
@ -3965,9 +3977,9 @@ void HistoryWidget::updateControlsVisibility() {
_pinnedBar->cancel.show();
_pinnedBar->shadow.show();
}
if (_firstLoadRequest) {
if (_firstLoadRequest && !_scroll.isHidden()) {
_scroll.hide();
} else {
} else if (!_firstLoadRequest && _scroll.isHidden()) {
_scroll.show();
}
if (_reportSpamStatus == dbiprsShowButton || _reportSpamStatus == dbiprsReportSent) {
@ -4578,7 +4590,10 @@ void HistoryWidget::delayedShowAt(MsgId showAtMsgId) {
void HistoryWidget::onScroll() {
App::checkImageCacheSize();
preloadHistoryIfNeeded();
visibleAreaUpdated();
}
void HistoryWidget::visibleAreaUpdated() {
if (_list && !_scroll.isHidden()) {
int st = _scroll.scrollTop();
_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;
if (needResize) {
_scroll.resize(width(), newScrollHeight);
visibleAreaUpdated();
_attachMention.setBoundings(_scroll.geometry());
_toHistoryEnd.move((width() - _toHistoryEnd.width()) / 2, _scroll.y() + _scroll.height() - _toHistoryEnd.height() - st::historyToEndSkip);
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()))) {
int32 addToY = 0;
int addToY = 0;
if (change.type == ScrollChangeAdd) {
addToY = change.value;
} else if (change.type == ScrollChangeOldHistoryHeight) {
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;
}
@ -6511,7 +6534,12 @@ void HistoryWidget::updateListSize(bool initial, bool loadedDown, const ScrollCh
}
} 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) {

View File

@ -139,22 +139,30 @@ private:
HistoryItem *nextItem(HistoryItem *item);
void updateDragSelection(HistoryItem *dragSelFrom, HistoryItem *dragSelTo, bool dragSelecting, bool force = false);
PeerData *_peer;
History *_migrated, *_history;
int32 _historyOffset, _historySkipHeight; // height of first date and first sys msg
PeerData *_peer = nullptr;
History *_migrated = nullptr;
History *_history = nullptr;
int _historyOffset = 0;
BotInfo *_botInfo;
int32 _botDescWidth, _botDescHeight;
// with migrated history we perhaps do not need to display first _history message
// (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;
HistoryWidget *_widget;
ScrollArea *_scroll;
mutable History *_curHistory;
mutable int32 _curBlock, _curItem;
HistoryWidget *_widget = nullptr;
ScrollArea *_scroll = nullptr;
mutable History *_curHistory = nullptr;
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;
SelectedItems _selected;
void applyDragSelection();
@ -168,36 +176,60 @@ private:
PrepareSelect = 0x03,
Selecting = 0x04,
};
DragAction _dragAction;
TextSelectType _dragSelType;
DragAction _dragAction = NoDrag;
TextSelectType _dragSelType = TextSelectLetters;
QPoint _dragStartPos, _dragPos;
HistoryItem *_dragItem;
HistoryCursorState _dragCursorState;
uint16 _dragSymbol;
bool _dragWasInactive;
HistoryItem *_dragItem = nullptr;
HistoryCursorState _dragCursorState = HistoryDefaultCursorState;
uint16 _dragSymbol = 0;
bool _dragWasInactive = false;
QPoint _trippleClickPoint;
QTimer _trippleClickTimer;
TextLinkPtr _contextMenuLnk;
HistoryItem *_dragSelFrom, *_dragSelTo;
bool _dragSelecting;
bool _wasSelectedText; // was some text selected in current drag action
HistoryItem *_dragSelFrom = nullptr;
HistoryItem *_dragSelTo = nullptr;
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;
QTimer _touchSelectTimer;
TouchScrollState _touchScrollState;
bool _touchPrevPosValid, _touchWaitingAcceleration;
TouchScrollState _touchScrollState = TouchScrollManual;
bool _touchPrevPosValid = false;
bool _touchWaitingAcceleration = false;
QPoint _touchSpeed;
uint64 _touchSpeedTime, _touchAccelerationTime, _touchTime;
uint64 _touchSpeedTime = 0;
uint64 _touchAccelerationTime = 0;
uint64 _touchTime = 0;
QTimer _touchScrollTimer;
PopupMenu *_menu;
// context menu
PopupMenu *_menu = nullptr;
// save visible area coords for painting / pressing userpics
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:
MsgId _replyToId;
MsgId _replyToId = 0;
Text _replyToName;
int32 _replyToNameVersion;
int _replyToNameVersion = 0;
void updateReplyToName();
MsgId _editMsgId;
MsgId _editMsgId = 0;
HistoryItem *_replyEditMsg;
HistoryItem *_replyEditMsg = nullptr;
Text _replyEditMsgText;
IconedButton _fieldBarCancel;
@ -737,13 +769,13 @@ private:
struct PinnedBar {
PinnedBar(MsgId msgId, HistoryWidget *parent);
MsgId msgId;
HistoryItem *msg;
MsgId msgId = 0;
HistoryItem *msg = nullptr;
Text text;
IconedButton cancel;
PlainShadow shadow;
};
PinnedBar *_pinnedBar;
PinnedBar *_pinnedBar = nullptr;
void updatePinnedBar(bool force = false);
bool pinnedMsgVisibilityUpdated();
void destroyPinnedBar();
@ -767,32 +799,33 @@ private:
// destroys _history and _migrated unread bars
void destroyUnreadBar();
mtpRequestId _saveEditMsgRequestId;
mtpRequestId _saveEditMsgRequestId = 0;
void saveEditMsg();
void saveEditMsgDone(History *history, const MTPUpdates &updates, mtpRequestId req);
bool saveEditMsgFail(History *history, const RPCError &error, mtpRequestId req);
DBIPeerReportSpamStatus _reportSpamStatus;
mtpRequestId _reportSpamSettingRequestId;
static const mtpRequestId ReportSpamRequestNeeded = -1;
DBIPeerReportSpamStatus _reportSpamStatus = dbiprsUnknown;
mtpRequestId _reportSpamSettingRequestId = ReportSpamRequestNeeded;
void updateReportSpamStatus();
void requestReportSpamSetting();
void reportSpamSettingDone(const MTPPeerSettings &result, mtpRequestId req);
bool reportSpamSettingFail(const RPCError &error, mtpRequestId req);
QString _previewLinks;
WebPageData *_previewData;
WebPageData *_previewData = nullptr;
typedef QMap<QString, WebPageId> PreviewCache;
PreviewCache _previewCache;
mtpRequestId _previewRequest;
Text _previewTitle, _previewDescription;
mtpRequestId _previewRequest = 0;
Text _previewTitle;
Text _previewDescription;
SingleTimer _previewTimer;
bool _previewCancelled;
bool _previewCancelled = false;
void gotPreview(QString links, const MTPMessageMedia &media, mtpRequestId req);
bool _replyForwardPressed;
bool _replyForwardPressed = false;
HistoryItem *_replyReturn;
HistoryItem *_replyReturn = nullptr;
QList<MsgId> _replyReturns;
bool messagesFailed(const RPCError &error, mtpRequestId requestId);
@ -824,11 +857,11 @@ private:
void countHistoryShowFrom();
mtpRequestId _stickersUpdateRequest;
mtpRequestId _stickersUpdateRequest = 0;
void stickersGot(const MTPmessages_AllStickers &stickers);
bool stickersFailed(const RPCError &error);
mtpRequestId _savedGifsUpdateRequest;
mtpRequestId _savedGifsUpdateRequest = 0;
void savedGifsGot(const MTPmessages_SavedGifs &gifs);
bool savedGifsFailed(const RPCError &error);
@ -840,39 +873,51 @@ private:
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 hasBroadcastToggle() const;
bool hasSilentToggle() const;
PeerData *_peer, *_clearPeer; // cache _peer in _clearPeer when showing clear history box
ChannelId _channel;
bool _canSendMessages;
MsgId _showAtMsgId, _fixedInScrollMsgId;
int32 _fixedInScrollMsgTop;
PeerData *_peer = nullptr;
mtpRequestId _firstLoadRequest, _preloadRequest, _preloadDownRequest;
// cache current _peer in _clearPeer when showing clear history box
PeerData *_clearPeer = nullptr;
MsgId _delayedShowAtMsgId;
mtpRequestId _delayedShowAtRequest;
ChannelId _channel = NoChannel;
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;
HistoryInner *_list;
History *_migrated, *_history;
bool _histInited; // initial updateListSize() called
HistoryInner *_list = nullptr;
History *_migrated = nullptr;
History *_history = nullptr;
bool _histInited = false; // initial updateListSize() called
int32 _lastScroll;
uint64 _lastScrolled;
int32 _lastScroll = 0;
uint64 _lastScrolled = 0;
QTimer _updateHistoryItems; // gifs optimization
IconedButton _toHistoryEnd;
CollapseButton _collapseComments;
MentionsDropdown _attachMention;
UserData *_inlineBot;
UserData *_inlineBot = nullptr;
QString _inlineBotUsername;
mtpRequestId _inlineBotResolveRequestId;
mtpRequestId _inlineBotResolveRequestId = 0;
void inlineBotResolveDone(const MTPcontacts_ResolvedPeer &result);
bool inlineBotResolveFail(QString name, const RPCError &error);
@ -885,46 +930,52 @@ private:
ReportSpamPanel _reportSpamPanel;
FlatButton _send, _unblock, _botStart, _joinChannel, _muteUnmute;
mtpRequestId _unblockRequest, _reportSpamRequest;
mtpRequestId _unblockRequest = 0;
mtpRequestId _reportSpamRequest = 0;
IconedButton _attachDocument, _attachPhoto;
EmojiButton _attachEmoji;
IconedButton _kbShow, _kbHide, _cmdStart;
FlatCheckbox _broadcast;
SilentToggle _silent;
bool _cmdStartShown;
bool _cmdStartShown = false;
MessageField _field;
Animation _a_record, _a_recording;
bool _recording, _inRecord, _inField, _inReplyEdit, _inPinnedMsg;
anim::ivalue a_recordingLevel;
int32 _recordingSamples;
anim::fvalue a_recordOver, a_recordDown;
bool _recording = false;
bool _inRecord = false;
bool _inField = false;
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;
int32 _recordCancelWidth;
bool kbWasHidden() const;
bool _kbShown;
HistoryItem *_kbReplyTo;
bool _kbShown = false;
HistoryItem *_kbReplyTo = nullptr;
ScrollArea _kbScroll;
BotKeyboard _keyboard;
Dropdown _attachType;
EmojiPan _emojiPan;
DragState _attachDrag;
DragState _attachDrag = DragStateNone;
DragArea _attachDragDocument, _attachDragPhoto;
int32 _selCount; // < 0 - text selected, focus list, not _field
TaskQueue _fileLoader;
int32 _textUpdateEventsFlags;
int32 _textUpdateEventsFlags = (TextUpdateEventsSaveDraft | TextUpdateEventsSendTyping);
int64 _serviceImageCacheSize;
int64 _serviceImageCacheSize = 0;
QString _confirmSource;
uint64 _confirmWithTextId;
uint64 _confirmWithTextId = 0;
QString _titlePeerText;
int32 _titlePeerTextWidth;
int32 _titlePeerTextWidth = 0;
Animation _a_show;
QPixmap _cacheUnder, _cacheOver, _cacheTopBarUnder, _cacheTopBarOver;
@ -932,20 +983,20 @@ private:
anim::fvalue a_shadow;
QTimer _scrollTimer;
int32 _scrollDelta;
int32 _scrollDelta = 0;
QTimer _animActiveTimer;
float64 _animActiveStart;
float64 _animActiveStart = 0;
QMap<QPair<History*, SendActionType>, mtpRequestId> _sendActionRequests;
QTimer _sendActionStopTimer;
uint64 _saveDraftStart;
bool _saveDraftText;
uint64 _saveDraftStart = 0;
bool _saveDraftText = false;
QTimer _saveDraftTimer;
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
FILEVERSION 0,9,34,1
PRODUCTVERSION 0,9,34,1
FILEVERSION 0,9,34,2
PRODUCTVERSION 0,9,34,2
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -51,10 +51,10 @@ BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", "Telegram Messenger LLP"
VALUE "FileVersion", "0.9.34.1"
VALUE "FileVersion", "0.9.34.2"
VALUE "LegalCopyright", "Copyright (C) 2014-2016"
VALUE "ProductName", "Telegram Desktop"
VALUE "ProductVersion", "0.9.34.1"
VALUE "ProductVersion", "0.9.34.2"
END
END
BLOCK "VarFileInfo"

View File

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