diff --git a/Telegram/SourceFiles/app.cpp b/Telegram/SourceFiles/app.cpp index a0c495014..934a9a5fa 100644 --- a/Telegram/SourceFiles/app.cpp +++ b/Telegram/SourceFiles/app.cpp @@ -2505,9 +2505,9 @@ namespace App { ChannelReplyMarkups::iterator i = channelReplyMarkups.find(channelId); if (i != channelReplyMarkups.cend()) { i->remove(msgId); - } - if (i->isEmpty()) { - channelReplyMarkups.erase(i); + if (i->isEmpty()) { + channelReplyMarkups.erase(i); + } } } } diff --git a/Telegram/SourceFiles/history.cpp b/Telegram/SourceFiles/history.cpp index b612be201..6f88cf71e 100644 --- a/Telegram/SourceFiles/history.cpp +++ b/Telegram/SourceFiles/history.cpp @@ -7494,6 +7494,8 @@ void HistoryServiceMsg::setMessageByAction(const MTPmessageAction &action) { second = TextLinkPtr(new PeerLink(u1)); third = TextLinkPtr(new PeerLink(u2)); text = lng_action_add_user_and_user(lt_from, from, lt_user, textcmdLink(2, u1->name), lt_second_user, textcmdLink(3, u2->name)); + } else if (v.isEmpty()) { + text = lng_action_add_user(lt_from, from, lt_user, "somebody"); } else { UserData *u = App::user(peerFromUser(foundSelf ? MTP::authedId() : v.at(0).v)); second = TextLinkPtr(new PeerLink(u)); diff --git a/Telegram/SourceFiles/history.h b/Telegram/SourceFiles/history.h index fe37497ac..a617c35b8 100644 --- a/Telegram/SourceFiles/history.h +++ b/Telegram/SourceFiles/history.h @@ -347,6 +347,13 @@ public: MediaOverviewIds overviewIds[OverviewCount]; int32 overviewCount[OverviewCount]; // -1 - not loaded, 0 - all loaded, > 0 - count, but not all loaded + bool overviewCountKnown(int32 overviewIndex) const { + return overviewCount[overviewIndex] >= 0; + } + int32 overviewCountValue(int32 overviewIndex) const { + return (overviewCount[overviewIndex] == 0) ? overview[overviewIndex].size() : overviewCount[overviewIndex]; + } + private: friend class HistoryBlock; diff --git a/Telegram/SourceFiles/historywidget.cpp b/Telegram/SourceFiles/historywidget.cpp index 04ea91987..d94a67004 100644 --- a/Telegram/SourceFiles/historywidget.cpp +++ b/Telegram/SourceFiles/historywidget.cpp @@ -1210,7 +1210,7 @@ int32 HistoryInner::recountHeight(HistoryItem *resizedItem) { } } if (skip != _historySkipHeight) { - if (st1 >= 0) st1 -= (_historySkipHeight - skip); + if (st1 >= 0) st1 -= (skip - _historySkipHeight); _historySkipHeight = skip; } updateBotInfo(false); diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index 6b6f86d06..b1e1fc864 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -1291,29 +1291,30 @@ void MainWidget::searchMessages(const QString &query, PeerData *inPeer) { } } +bool MainWidget::preloadOverview(PeerData *peer, MediaOverviewType type) { + MTPMessagesFilter filter = typeToMediaFilter(type); + if (type == OverviewCount) return false; + + History *h = App::history(peer->id); + if (h->overviewCount[type] >= 0 || _overviewPreload[type].constFind(peer) != _overviewPreload[type].cend()) { + return false; + } + + int32 flags = (peer->isChannel() && !peer->isMegagroup()) ? MTPmessages_Search::flag_important_only : 0; + _overviewPreload[type].insert(peer, MTP::send(MTPmessages_Search(MTP_int(flags), peer->input, MTP_string(""), filter, MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(0)), rpcDone(&MainWidget::overviewPreloaded, peer), rpcFail(&MainWidget::overviewFailed, peer), 0, 10)); + return true; +} + void MainWidget::preloadOverviews(PeerData *peer) { History *h = App::history(peer->id); - bool sending[OverviewCount] = { false }; + bool sending = false; for (int32 i = 0; i < OverviewCount; ++i) { - if (h->overviewCount[i] < 0) { - if (_overviewPreload[i].constFind(peer) == _overviewPreload[i].cend()) { - sending[i] = true; - } + if (preloadOverview(peer, MediaOverviewType(i))) { + sending = true; } } - int32 last = OverviewCount; - while (last > 0) { - if (sending[--last]) break; - } - for (int32 i = 0; i < OverviewCount; ++i) { - if (sending[i]) { - MediaOverviewType type = MediaOverviewType(i); - MTPMessagesFilter filter = typeToMediaFilter(type); - if (type == OverviewCount) break; - - int32 flags = (peer->isChannel() && !peer->isMegagroup()) ? MTPmessages_Search::flag_important_only : 0; - _overviewPreload[i].insert(peer, MTP::send(MTPmessages_Search(MTP_int(flags), peer->input, MTP_string(""), filter, MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(0)), rpcDone(&MainWidget::overviewPreloaded, peer), rpcFail(&MainWidget::overviewFailed, peer), 0, (i == last) ? 0 : 10)); - } + if (sending) { + MTP::sendAnything(); } } @@ -1381,15 +1382,18 @@ void MainWidget::overviewPreloaded(PeerData *peer, const MTPmessages_Messages &r void MainWidget::mediaOverviewUpdated(PeerData *peer, MediaOverviewType type) { if (profile) profile->mediaOverviewUpdated(peer, type); if (!_player.isHidden()) _player.mediaOverviewUpdated(peer, type); - if (overview && overview->peer() == peer) { + if (overview && (overview->peer() == peer || overview->peer()->migrateFrom() == peer)) { overview->mediaOverviewUpdated(peer, type); int32 mask = 0; - History *h = peer ? App::historyLoaded(peer->id) : 0; + History *h = peer ? App::historyLoaded((peer->migrateTo() ? peer->migrateTo() : peer)->id) : 0; + History *m = (peer && peer->migrateFrom()) ? App::historyLoaded(peer->migrateFrom()->id) : 0; if (h) { for (int32 i = 0; i < OverviewCount; ++i) { if (!h->overview[i].isEmpty() || h->overviewCount[i] > 0 || i == overview->type()) { mask |= (1 << i); + } else if (m && (!m->overview[i].isEmpty() || m->overviewCount[i] > 0)) { + mask |= (1 << i); } } } diff --git a/Telegram/SourceFiles/mainwidget.h b/Telegram/SourceFiles/mainwidget.h index dcfa94523..4eeac7eb7 100644 --- a/Telegram/SourceFiles/mainwidget.h +++ b/Telegram/SourceFiles/mainwidget.h @@ -333,6 +333,7 @@ public: void insertBotCommand(const QString &cmd); void searchMessages(const QString &query, PeerData *inPeer); + bool preloadOverview(PeerData *peer, MediaOverviewType type); void preloadOverviews(PeerData *peer); void mediaOverviewUpdated(PeerData *peer, MediaOverviewType type); void changingMsgId(HistoryItem *row, MsgId newId); diff --git a/Telegram/SourceFiles/mediaview.cpp b/Telegram/SourceFiles/mediaview.cpp index 394b59324..7c0d23b4b 100644 --- a/Telegram/SourceFiles/mediaview.cpp +++ b/Telegram/SourceFiles/mediaview.cpp @@ -61,23 +61,66 @@ namespace { }; } -MediaView::MediaView() : TWidget(App::wnd()), -_photo(0), _doc(0), _overview(OverviewCount), -_leftNavVisible(false), _rightNavVisible(false), _saveVisible(false), _headerHasLink(false), _animStarted(getms()), -_width(0), _x(0), _y(0), _w(0), _h(0), _xStart(0), _yStart(0), -_zoom(0), _zoomToScreen(0), _pressed(false), _dragging(0), _full(-1), -_docNameWidth(0), _docSizeWidth(0), -_docThumbx(0), _docThumby(0), _docThumbw(0), -_docRadialFirst(0), _docRadialStart(0), _docRadialLast(0), _docRadialOpacity(1), a_docRadialStart(0, 1), -_docDownload(this, lang(lng_media_download), st::mvDocLink), -_docSaveAs(this, lang(lng_mediaview_save_as), st::mvDocLink), -_docCancel(this, lang(lng_cancel), st::mvDocLink), -_history(0), _peer(0), _user(0), _from(0), _index(-1), _msgid(0), _channel(NoChannel), _canForward(false), _canDelete(false), -_loadRequest(0), _over(OverNone), _down(OverNone), _lastAction(-st::mvDeltaFromLastAction, -st::mvDeltaFromLastAction), _ignoringDropdown(false), -_controlsState(ControlsShown), _controlsAnimStarted(0), -_menu(0), _dropdown(this, st::mvDropdown), _receiveMouse(true), _touchPress(false), _touchMove(false), _touchRightButton(false), -_saveMsgStarted(0), _saveMsgOpacity(0) -{ +MediaView::MediaView() : TWidget(App::wnd()) +, _photo(0) +, _doc(0) +, _overview(OverviewCount) +, _leftNavVisible(false) +, _rightNavVisible(false) +, _saveVisible(false) +, _headerHasLink(false) +, _animStarted(getms()) +, _width(0) +, _x(0) +, _y(0) +, _w(0) +, _h(0) +, _xStart(0) +, _yStart(0) +, _zoom(0) +, _zoomToScreen(0) +, _pressed(false) +, _dragging(0) +, _full(-1) +, _docNameWidth(0) +, _docSizeWidth(0) +, _docThumbx(0) +, _docThumby(0) +, _docThumbw(0) +, _docRadialFirst(0) +, _docRadialStart(0) +, _docRadialLast(0) +, _docRadialOpacity(1) +, a_docRadialStart(0, 1) +, _docDownload(this, lang(lng_media_download), st::mvDocLink) +, _docSaveAs(this, lang(lng_mediaview_save_as), st::mvDocLink) +, _docCancel(this, lang(lng_cancel), st::mvDocLink) +, _migrated(0) +, _history(0) +, _peer(0) +, _user(0) +, _from(0) +, _index(-1) +, _msgid(0) +, _msgmigrated(false) +, _channel(NoChannel) +, _canForward(false) +, _canDelete(false) +, _loadRequest(0) +, _over(OverNone) +, _down(OverNone) +, _lastAction(-st::mvDeltaFromLastAction, -st::mvDeltaFromLastAction) +, _ignoringDropdown(false) +, _controlsState(ControlsShown) +, _controlsAnimStarted(0) +, _menu(0) +, _dropdown(this, st::mvDropdown) +, _receiveMouse(true) +, _touchPress(false) +, _touchMove(false) +, _touchRightButton(false) +, _saveMsgStarted(0) +, _saveMsgOpacity(0) { TextCustomTagsMap custom; custom.insert(QChar('c'), qMakePair(textcmdStartLink(1), textcmdStopLink())); _saveMsgText.setRichText(st::medviewSaveMsgFont, lang(lng_mediaview_saved), _textDlgOptions, custom); @@ -160,12 +203,21 @@ void MediaView::moveToScreen() { void MediaView::mediaOverviewUpdated(PeerData *peer, MediaOverviewType type) { if (!_photo && !_doc) return; - if (_history && _history->peer == peer && type == _overview) { + if (_history && (_history->peer == peer || (_migrated && _migrated->peer == peer)) && type == _overview) { _index = -1; - for (int i = 0, l = _history->overview[_overview].size(); i < l; ++i) { - if (_history->overview[_overview].at(i) == _msgid) { - _index = i; - break; + if (_msgmigrated) { + for (int i = 0, l = _migrated->overview[_overview].size(); i < l; ++i) { + if (_migrated->overview[_overview].at(i) == _msgid) { + _index = i; + break; + } + } + } else { + for (int i = 0, l = _history->overview[_overview].size(); i < l; ++i) { + if (_history->overview[_overview].at(i) == _msgid) { + _index = i; + break; + } } } updateControls(); @@ -282,7 +334,7 @@ void MediaView::updateControls() { d = date(_photo->date); } else if (_doc) { d = date(_doc->date); - } else if (HistoryItem *item = App::histItemById(_channel, _msgid)) { + } else if (HistoryItem *item = App::histItemById(_msgmigrated ? 0 : _channel, _msgid)) { d = item->date; } if (d.date() == dNow.date()) { @@ -301,14 +353,19 @@ void MediaView::updateControls() { _dateNav = myrtlrect(st::mvTextLeft, height() - st::mvTextTop, st::mvFont->width(_dateText), st::mvFont->height); } updateHeader(); - if (_photo || (_history && _overview == OverviewPhotos)) { - _leftNavVisible = (_index > 0) || (_index == 0 && _history && _history->overview[_overview].size() < _history->overviewCount[_overview]); + if (_photo || (_history && (_overview == OverviewPhotos || _overview == OverviewDocuments))) { + _leftNavVisible = (_index > 0) || (_index == 0 && ( + (!_msgmigrated && _history && _history->overview[_overview].size() < _history->overviewCount[_overview]) || + (_msgmigrated && _migrated && _migrated->overview[_overview].size() < _migrated->overviewCount[_overview]) || + (!_msgmigrated && _history && _migrated && (!_migrated->overview[_overview].isEmpty() || _migrated->overviewCount[_overview] > 0)))); _rightNavVisible = (_index >= 0) && ( - (_history && _index + 1 < _history->overview[_overview].size()) || - (_user && (_index + 1 < _user->photos.size() || _index + 1 < _user->photosCount))); - } else if (_history && _overview == OverviewDocuments) { - _leftNavVisible = (_index > 0) || (_index == 0 && _history && _history->overview[_overview].size() < _history->overviewCount[_overview]); - _rightNavVisible = (_index >= 0) && _history && (_index + 1 < _history->overview[_overview].size()); + (!_msgmigrated && _history && _index + 1 < _history->overview[_overview].size()) || + (_msgmigrated && _migrated && _index + 1 < _migrated->overview[_overview].size()) || + (_msgmigrated && _migrated && _history && (!_history->overview[_overview].isEmpty() || _history->overviewCount[_overview] > 0)) || + (!_history && _user && (_index + 1 < _user->photos.size() || _index + 1 < _user->photosCount))); + if (_msgmigrated && _history->overview[_overview].size() < _history->overviewCountValue(_overview)) { + _leftNavVisible = _rightNavVisible = false; + } } else { _leftNavVisible = _rightNavVisible = false; } @@ -399,7 +456,7 @@ bool MediaView::animStep(float64 msp) { QString fname(_doc->already(true)); QImageReader reader(fname); if (reader.canRead()) { - displayDocument(_doc, App::histItemById(_channel, _msgid)); + displayDocument(_doc, App::histItemById(_msgmigrated ? 0 : _channel, _msgid)); } } } else { @@ -461,7 +518,7 @@ void MediaView::onDropdownHiding() { } void MediaView::onToMessage() { - if (HistoryItem *item = _msgid ? App::histItemById(_channel, _msgid) : 0) { + if (HistoryItem *item = _msgid ? App::histItemById(_msgmigrated ? 0 : _channel, _msgid) : 0) { if (App::wnd()) { close(); if (App::main()) App::main()->showPeerHistory(item->history()->peer->id, _msgid); @@ -519,6 +576,9 @@ void MediaView::onSaveAs() { } } } + activateWindow(); + App::app()->setActiveWindow(this); + setFocus(); } void MediaView::onDocClick() { @@ -599,7 +659,7 @@ void MediaView::onShowInFolder() { } void MediaView::onForward() { - HistoryItem *item = App::histItemById(_channel, _msgid); + HistoryItem *item = App::histItemById(_msgmigrated ? 0 : _channel, _msgid); if (!_msgid || !item) return; if (App::wnd()) { @@ -620,7 +680,7 @@ void MediaView::onDelete() { App::app()->peerClearPhoto(_photo->peer->id); } } else { - HistoryItem *item = App::histItemById(_channel, _msgid); + HistoryItem *item = App::histItemById(_msgmigrated ? 0 : _channel, _msgid); if (item) { App::contextItem(item); App::main()->deleteLayer(); @@ -658,6 +718,16 @@ void MediaView::onCopy() { void MediaView::showPhoto(PhotoData *photo, HistoryItem *context) { _history = context ? context->history() : 0; + if (_history) { + if (_history->peer->migrateFrom()) { + _migrated = App::history(_history->peer->migrateFrom()->id); + } else if (_history->peer->migrateTo()) { + _migrated = _history; + _history = App::history(_history->peer->migrateTo()->id); + } + } else { + _migrated = 0; + } _peer = 0; _user = 0; _saveMsgStarted = 0; @@ -674,7 +744,8 @@ void MediaView::showPhoto(PhotoData *photo, HistoryItem *context) { _index = -1; _msgid = context ? context->id : 0; - _channel = context ? context->channelId() : NoChannel; + _msgmigrated = context ? (context->history() == _migrated) : false; + _channel = _history ? _history->channelId() : NoChannel; _canForward = _msgid > 0; _canDelete = context ? context->canDelete() : false; _photo = photo; @@ -689,7 +760,7 @@ void MediaView::showPhoto(PhotoData *photo, HistoryItem *context) { } void MediaView::showPhoto(PhotoData *photo, PeerData *context) { - _history = 0; + _history = _migrated = 0; _peer = context; _user = context->asUser(); _saveMsgStarted = 0; @@ -703,6 +774,7 @@ void MediaView::showPhoto(PhotoData *photo, PeerData *context) { if (!_animOpacities.isEmpty()) _animOpacities.clear(); _msgid = 0; + _msgmigrated = false; _channel = NoChannel; _canForward = _canDelete = false; _index = -1; @@ -731,6 +803,16 @@ void MediaView::showPhoto(PhotoData *photo, PeerData *context) { void MediaView::showDocument(DocumentData *doc, HistoryItem *context) { _photo = 0; _history = context ? context->history() : 0; + if (_history) { + if (_history->peer->migrateFrom()) { + _migrated = App::history(_history->peer->migrateFrom()->id); + } else if (_history->peer->migrateTo()) { + _migrated = _history; + _history = App::history(_history->peer->migrateTo()->id); + } + } else { + _migrated = 0; + } _saveMsgStarted = 0; _peer = 0; _user = 0; @@ -747,22 +829,13 @@ void MediaView::showDocument(DocumentData *doc, HistoryItem *context) { _index = -1; _msgid = context ? context->id : 0; - _channel = context ? context->channelId() : NoChannel; + _msgmigrated = context ? (context->history() == _migrated) : false; + _channel = _history ? _history->channelId() : NoChannel; _canForward = _msgid > 0; _canDelete = context ? context->canDelete() : false; if (_history) { _overview = OverviewDocuments; - - for (int i = 0, l = _history->overview[_overview].size(); i < l; ++i) { - if (_history->overview[_overview].at(i) == _msgid) { - _index = i; - break; - } - } - - if (_history->overviewCount[_overview] < 0) { - loadBack(); - } + findCurrent(); } displayDocument(doc, context); preloadData(0); @@ -818,6 +891,8 @@ void MediaView::displayPhoto(PhotoData *photo, HistoryItem *item) { psUpdateOverlayed(this); show(); psShowOverAll(this); + activateWindow(); + setFocus(); } } @@ -990,6 +1065,9 @@ void MediaView::displayDocument(DocumentData *doc, HistoryItem *item) { // empty psUpdateOverlayed(this); show(); psShowOverAll(this); + activateWindow(); + App::app()->setActiveWindow(this); + setFocus(); } } @@ -1399,15 +1477,29 @@ void MediaView::keyPressEvent(QKeyEvent *e) { } void MediaView::moveToNext(int32 delta) { - if (_index < 0 || (_history && _overview != OverviewPhotos && _overview != OverviewDocuments) || (_overview == OverviewCount && !_user)) return; + if (_index < 0 || (_history && _overview != OverviewPhotos && _overview != OverviewDocuments) || (_overview == OverviewCount && !_user)) { + return; + } + if (_msgmigrated && _history->overview[_overview].size() < _history->overviewCountValue(_overview)) { + return; + } int32 newIndex = _index + delta; if (_history && _overview != OverviewCount) { - if (newIndex >= 0 && newIndex < _history->overview[_overview].size()) { - _index = newIndex; - if (HistoryItem *item = App::histItemById(_history->channelId(), _history->overview[_overview][_index])) { + bool newMigrated = _msgmigrated; + if (!newMigrated && newIndex < 0 && _migrated) { + newIndex += _migrated->overview[_overview].size(); + newMigrated = true; + } else if (newMigrated && newIndex >= _migrated->overview[_overview].size()) { + newIndex -= _migrated->overview[_overview].size() + (_history->overviewCountValue(_overview) - _history->overview[_overview].size()); + newMigrated = false; + } + if (newIndex >= 0 && newIndex < (newMigrated ? _migrated : _history)->overview[_overview].size()) { + if (HistoryItem *item = App::histItemById(newMigrated ? 0 : _channel, (newMigrated ? _migrated : _history)->overview[_overview][newIndex])) { + _index = newIndex; _msgid = item->id; - _channel = item->channelId(); + _msgmigrated = (item->history() == _migrated); + _channel = _history ? _history->channelId() : NoChannel; _canForward = _msgid > 0; _canDelete = item->canDelete(); if (item->getMedia()) { @@ -1440,12 +1532,21 @@ void MediaView::moveToNext(int32 delta) { void MediaView::preloadData(int32 delta) { if (_index < 0 || (!_user && _overview == OverviewCount)) return; - int32 from = _index + (delta ? delta : -1), to = _index + (delta ? delta * MediaOverviewPreloadCount : 1), forget = _index - delta * 2; + int32 from = _index + (delta ? delta : -1), to = _index + (delta ? delta * MediaOverviewPreloadCount : 1); if (from > to) qSwap(from, to); if (_history && _overview != OverviewCount) { for (int32 i = from; i <= to; ++i) { - if (i >= 0 && i < _history->overview[_overview].size() && i != _index) { - if (HistoryItem *item = App::histItemById(_history->channelId(), _history->overview[_overview][i])) { + History *previewHistory = _msgmigrated ? _migrated : _history; + int32 previewIndex = i; + if (_msgmigrated && previewIndex >= _migrated->overview[_overview].size()) { + previewHistory = _history; + previewIndex -= _migrated->overview[_overview].size() + (_history->overviewCountValue(_overview) - _history->overview[_overview].size()); + } else if (!_msgmigrated && previewIndex < 0) { + previewHistory = _migrated; + previewIndex += _migrated->overview[_overview].size(); + } + if (previewIndex >= 0 && previewIndex < previewHistory->overview[_overview].size() && (previewHistory != (_msgmigrated ? _migrated : _history) || previewIndex != _index)) { + if (HistoryItem *item = App::histItemById(previewHistory->channelId(), previewHistory->overview[_overview][previewIndex])) { if (HistoryMedia *media = item->getMedia()) { switch (media->type()) { case MediaTypePhoto: static_cast(media)->photo()->full->load(); break; @@ -1456,8 +1557,17 @@ void MediaView::preloadData(int32 delta) { } } } - if (forget >= 0 && forget < _history->overview[_overview].size() && forget != _index) { - if (HistoryItem *item = App::histItemById(_history->channelId(), _history->overview[_overview][forget])) { + int32 forgetIndex = _index - delta * 2; + History *forgetHistory = _msgmigrated ? _migrated : _history; + if (_msgmigrated && forgetIndex >= _migrated->overview[_overview].size()) { + forgetHistory = _history; + forgetIndex -= _migrated->overview[_overview].size() + (_history->overviewCountValue(_overview) - _history->overview[_overview].size()); + } else if (!_msgmigrated && forgetIndex < 0) { + forgetHistory = _migrated; + forgetIndex += _migrated->overview[_overview].size(); + } + if (forgetIndex >= 0 && forgetIndex < forgetHistory->overview[_overview].size() && (forgetHistory != (_msgmigrated ? _migrated : _history) || forgetIndex != _index)) { + if (HistoryItem *item = App::histItemById(forgetHistory->channelId(), forgetHistory->overview[_overview][forgetIndex])) { if (HistoryMedia *media = item->getMedia()) { switch (media->type()) { case MediaTypePhoto: static_cast(media)->photo()->forget(); break; @@ -1478,8 +1588,9 @@ void MediaView::preloadData(int32 delta) { _user->photos[i]->full->load(); } } - if (forget >= 0 && forget < _user->photos.size() && forget != _index) { - _user->photos[forget]->forget(); + int32 forgetIndex = _index - delta * 2; + if (forgetIndex >= 0 && forgetIndex < _user->photos.size() && forgetIndex != _index) { + _user->photos[forgetIndex]->forget(); } } } @@ -1676,11 +1787,11 @@ void MediaView::mouseReleaseEvent(QMouseEvent *e) { TextLinkPtr lnk = textlnkDown(); textlnkDown(TextLinkPtr()); if (lnk && textlnkOver() == lnk) { - if (reHashtag().match(lnk->encoded()).hasMatch() && _history && _history->isChannel()) { + if (reHashtag().match(lnk->encoded()).hasMatch() && _history && _history->isChannel() && !_history->isMegagroup()) { App::wnd()->hideMediaview(); App::searchByHashtag(lnk->encoded(), _history->peer); } else { - if (reBotCommand().match(lnk->encoded()).hasMatch() && _history->peer->isUser() && _history->peer->asUser()->botInfo) { + if (reBotCommand().match(lnk->encoded()).hasMatch() && _history) { App::wnd()->hideMediaview(); App::main()->showPeerHistory(_history->peer->id, ShowAtTheEndMsgId); } @@ -1852,6 +1963,7 @@ void MediaView::onCheckActive() { if (App::wnd() && isVisible()) { if (App::wnd()->isActiveWindow() && App::wnd()->hasFocus()) { activateWindow(); + App::app()->setActiveWindow(this); setFocus(); } } @@ -1866,23 +1978,53 @@ void MediaView::updateImage() { } void MediaView::findCurrent() { - for (int i = 0, l = _history->overview[_overview].size(); i < l; ++i) { - if (_history->overview[_overview].at(i) == _msgid) { - _index = i; - break; + if (_msgmigrated) { + for (int i = 0, l = _migrated->overview[_overview].size(); i < l; ++i) { + if (_migrated->overview[_overview].at(i) == _msgid) { + _index = i; + break; + } + } + if (_history->overviewCount[_overview] < 0) { + loadBack(); + } else if (_history->overviewCountValue(_overview) <= _history->overview[_overview].size()) { // all loaded + if (_migrated->overviewCount[_overview] < 0 || (_index < 2 && _migrated->overviewCount[_overview] > 0)) { + loadBack(); + } + } + } else { + for (int i = 0, l = _history->overview[_overview].size(); i < l; ++i) { + if (_history->overview[_overview].at(i) == _msgid) { + _index = i; + break; + } + } + if (_history->overviewCount[_overview] < 0 || (_index < 2 && _history->overviewCount[_overview] > 0) || (_index < 1 && _migrated && _migrated->overviewCount[_overview] != 0)) { + loadBack(); + } + if (_migrated && _migrated->overviewCount[_overview] < 0) { + App::main()->preloadOverview(_migrated->peer, _overview); } - } - - if (_history->overviewCount[_overview] < 0 || (!_index && _history->overviewCount[_overview] > 0)) { - loadBack(); } } void MediaView::loadBack() { if (_loadRequest || _index < 0 || (_overview == OverviewCount && !_user)) return; - if (_history && _overview != OverviewCount && _history->overviewCount[_overview] != 0) { - if (App::main()) App::main()->loadMediaBack(_history->peer, _overview); + if (_history && _overview != OverviewCount && (_history->overviewCount[_overview] != 0 || (_migrated && _migrated->overviewCount[_overview] != 0))) { + if (App::main()) { + if (_msgmigrated || (_migrated && _index == 0 && _history->overviewCount[_overview] >= 0 && _history->overviewCountValue(_overview) <= _history->overview[_overview].size())) { + App::main()->loadMediaBack(_migrated->peer, _overview); + } else { + App::main()->loadMediaBack(_history->peer, _overview); + if (_migrated && _index == 0 && _migrated->overviewCount[_overview] != 0 && _migrated->overview[_overview].isEmpty()) { + App::main()->loadMediaBack(_migrated->peer, _overview); + } + } + if (_msgmigrated && _history->overviewCount[_overview] < 0) { + App::main()->preloadOverview(_history->peer, _overview); + } + } } else if (_user && _user->photosCount != 0) { int32 limit = (_index < MediaOverviewStartPerPage && _user->photos.size() > MediaOverviewStartPerPage) ? SearchPerPage : MediaOverviewStartPerPage; _loadRequest = MTP::send(MTPphotos_GetUserPhotos(_user->inputUser, MTP_int(_user->photos.size()), MTP_long(0), MTP_int(limit)), rpcDone(&MediaView::userPhotosLoaded, _user)); @@ -1926,11 +2068,22 @@ void MediaView::userPhotosLoaded(UserData *u, const MTPphotos_Photos &photos, mt } void MediaView::updateHeader() { - int32 index = _index, count = 0; + int32 index = _index, count = 0, addcount = (_migrated && _overview != OverviewCount) ? _migrated->overviewCountValue(_overview) : 0; if (_history) { if (_overview != OverviewCount) { - count = _history->overviewCount[_overview] ? _history->overviewCount[_overview] : _history->overview[_overview].size(); - if (index >= 0) index += count - _history->overview[_overview].size(); + count = _history->overviewCountValue(_overview); + if (addcount >= 0 && count >= 0) { + count += addcount; + } + if (index >= 0 && (_msgmigrated ? (count >= 0 && addcount >= 0 && _history->overviewCountValue(_overview) <= _history->overview[_overview].size()) : (count >= 0))) { + if (_msgmigrated) { + index += addcount - _migrated->overview[_overview].size(); + } else { + index += count - _history->overview[_overview].size(); + } + } else { + count = 0; // unknown yet + } } } else if (_user) { count = _user->photosCount ? _user->photosCount : _user->photos.size(); diff --git a/Telegram/SourceFiles/mediaview.h b/Telegram/SourceFiles/mediaview.h index e546488bd..d87f2fec5 100644 --- a/Telegram/SourceFiles/mediaview.h +++ b/Telegram/SourceFiles/mediaview.h @@ -153,7 +153,7 @@ private: anim::fvalue a_docRadial, a_docRadialStart; LinkButton _docDownload, _docSaveAs, _docCancel; - History *_history; // if conversation photos or files overview + History *_migrated, *_history; // if conversation photos or files overview PeerData *_peer; UserData *_user; // if user profile photos overview @@ -162,6 +162,7 @@ private: int32 _index; // index in photos or files array, -1 if just photo MsgId _msgid; // msgId of current photo or file + bool _msgmigrated; // msgId is from _migrated history ChannelId _channel; bool _canForward, _canDelete; diff --git a/Telegram/SourceFiles/mtproto/mtp.h b/Telegram/SourceFiles/mtproto/mtp.h index acafe616c..295cc5ca5 100644 --- a/Telegram/SourceFiles/mtproto/mtp.h +++ b/Telegram/SourceFiles/mtproto/mtp.h @@ -110,6 +110,11 @@ namespace MTP { inline mtpRequestId send(const TRequest &request, RPCDoneHandlerPtr onDone, RPCFailHandlerPtr onFail = RPCFailHandlerPtr(), int32 dc = 0, uint64 msCanWait = 0, mtpRequestId after = 0) { return send(request, RPCResponseHandler(onDone, onFail), dc, msCanWait, after); } + inline void sendAnything(int32 dc = 0, uint64 msCanWait = 0) { + if (MTProtoSessionPtr session = _mtp_internal::getSession(dc)) { + return session->sendAnything(msCanWait); + } + } void ping(); void cancel(mtpRequestId req); void killSession(int32 dc); diff --git a/Telegram/SourceFiles/playerwidget.cpp b/Telegram/SourceFiles/playerwidget.cpp index 623f0a6d5..f61ffa048 100644 --- a/Telegram/SourceFiles/playerwidget.cpp +++ b/Telegram/SourceFiles/playerwidget.cpp @@ -42,7 +42,9 @@ PlayerWidget::PlayerWidget(QWidget *parent) : TWidget(parent) , _downFrequency(AudioVoiceMsgFrequency) , _downProgress(0.) , _stateAnim(animFunc(this, &PlayerWidget::stateStep)) +, _msgmigrated(false) , _index(-1) +, _migrated(0) , _history(0) , _timeWidth(0) , _repeat(false) @@ -265,14 +267,25 @@ void PlayerWidget::updateOverRect(OverState state) { void PlayerWidget::updateControls() { _fullAvailable = (_index >= 0); - _prevAvailable = _fullAvailable && (_index > 0); - _nextAvailable = _fullAvailable && (_index < _history->overview[OverviewAudioDocuments].size() - 1); + _prevAvailable = _fullAvailable && ((_index > 0) || (_index == 0 && _migrated && !_msgmigrated && !_migrated->overview[OverviewAudioDocuments].isEmpty())); + _nextAvailable = _fullAvailable && ((_index < (_msgmigrated ? _migrated : _history)->overview[OverviewAudioDocuments].size() - 1) || (_msgmigrated && _index == _migrated->overview[OverviewAudioDocuments].size() - 1 && _history->overviewCount[OverviewAudioDocuments] >= 0 && _history->overviewCountValue(OverviewAudioDocuments) <= _history->overview[OverviewAudioDocuments].size())); resizeEvent(0); update(); - if (_index >= 0 && _index < MediaOverviewStartPerPage) { - if (_history->overviewCount[OverviewAudioDocuments] < 0 || _history->overviewCount[OverviewAudioDocuments] > 0) { - if (App::main()) App::main()->loadMediaBack(_history->peer, OverviewAudioDocuments); + if (_history->overviewCount[OverviewAudioDocuments] != 0 || (_migrated && _migrated->overviewCount[OverviewAudioDocuments] != 0)) { + if (App::main()) { + if (_msgmigrated || (_migrated && _index == 0 && _history->overviewCount[OverviewAudioDocuments] >= 0 && _history->overviewCountValue(OverviewAudioDocuments) <= _history->overview[OverviewAudioDocuments].size())) { + App::main()->loadMediaBack(_migrated->peer, OverviewAudioDocuments); + } else { + App::main()->loadMediaBack(_history->peer, OverviewAudioDocuments); + if (_migrated && _index == 0 && _migrated->overviewCount[OverviewAudioDocuments] != 0 && _migrated->overview[OverviewAudioDocuments].isEmpty()) { + App::main()->loadMediaBack(_migrated->peer, OverviewAudioDocuments); + } + } + if (_msgmigrated && _history->overviewCount[OverviewAudioDocuments] < 0) { + App::main()->preloadOverview(_history->peer, OverviewAudioDocuments); + } + } } } } @@ -281,8 +294,8 @@ void PlayerWidget::findCurrent() { _index = -1; if (!_history) return; - const History::MediaOverview *o = &_history->overview[OverviewAudioDocuments]; - if (_history->channelId() == _song.msgId.channel) { + const History::MediaOverview *o = &(_msgmigrated ? _migrated : _history)->overview[OverviewAudioDocuments]; + if ((_msgmigrated ? _migrated : _history)->channelId() == _song.msgId.channel) { for (int i = 0, l = o->size(); i < l; ++i) { if (o->at(i) == _song.msgId.msg) { _index = i; @@ -292,15 +305,19 @@ void PlayerWidget::findCurrent() { } if (_index < 0) return; + HistoryItem *next = 0; if (_index < o->size() - 1) { - if (HistoryItem *next = App::histItemById(_history->channelId(), o->at(_index + 1))) { - if (HistoryDocument *document = static_cast(next->getMedia())) { - if (document->document()->already(true).isEmpty() && document->document()->data.isEmpty()) { - if (!document->document()->loader) { - DocumentOpenLink::doOpen(document->document()); - document->document()->openOnSave = 0; - document->document()->openOnSaveMsgId = FullMsgId(); - } + next = App::histItemById((_msgmigrated ? _migrated : _history)->channelId(), o->at(_index + 1)); + } else if (_msgmigrated && _index == o->size() - 1 && _history->overviewCount[OverviewAudioDocuments] >= 0 && _history->overviewCountValue(OverviewAudioDocuments) <= _history->overview[OverviewAudioDocuments].size()) { + next = App::histItemById(_history->channelId(), _history->overview[OverviewAudioDocuments].at(0)); + } + if (next) { + if (HistoryDocument *document = static_cast(next->getMedia())) { + if (document->document()->already(true).isEmpty() && document->document()->data.isEmpty()) { + if (!document->document()->loader) { + DocumentOpenLink::doOpen(document->document()); + document->document()->openOnSave = 0; + document->document()->openOnSaveMsgId = FullMsgId(); } } } @@ -324,11 +341,11 @@ void PlayerWidget::clearSelection() { } void PlayerWidget::mediaOverviewUpdated(PeerData *peer, MediaOverviewType type) { - if (_history && _history->peer == peer && type == OverviewAudioDocuments) { + if (_history && (_history->peer == peer || (_migrated && _migrated->peer == peer)) && type == OverviewAudioDocuments) { _index = -1; - if (_history->channelId() == _song.msgId.channel) { - for (int i = 0, l = _history->overview[OverviewAudioDocuments].size(); i < l; ++i) { - if (_history->overview[OverviewAudioDocuments].at(i) == _song.msgId.msg) { + if ((_msgmigrated ? _migrated : _history)->channelId() == _song.msgId.channel) { + for (int i = 0, l = (_msgmigrated ? _migrated : _history)->overview[OverviewAudioDocuments].size(); i < l; ++i) { + if ((_msgmigrated ? _migrated : _history)->overview[OverviewAudioDocuments].at(i) == _song.msgId.msg) { _index = i; break; } @@ -488,18 +505,26 @@ void PlayerWidget::playPausePressed() { void PlayerWidget::prevPressed() { if (isHidden()) return; - const History::MediaOverview *o = _history ? &_history->overview[OverviewAudioDocuments] : 0; + const History::MediaOverview *o = _history ? &(_msgmigrated ? _migrated : _history)->overview[OverviewAudioDocuments] : 0; if (audioPlayer() && o && _index > 0 && _index <= o->size() && !o->isEmpty()) { - startPlay(FullMsgId(_history->channelId(), o->at(_index - 1))); + startPlay(FullMsgId((_msgmigrated ? _migrated : _history)->channelId(), o->at(_index - 1))); + } else if (!_index && _history && _migrated && !_msgmigrated) { + o = &_migrated->overview[OverviewAudioDocuments]; + if (!o->isEmpty()) { + startPlay(FullMsgId(_migrated->channelId(), o->at(o->size() - 1))); + } } } void PlayerWidget::nextPressed() { if (isHidden()) return; - const History::MediaOverview *o = _history ? &_history->overview[OverviewAudioDocuments] : 0; + const History::MediaOverview *o = _history ? &(_msgmigrated ? _migrated : _history)->overview[OverviewAudioDocuments] : 0; if (audioPlayer() && o && _index >= 0 && _index < o->size() - 1) { - startPlay(FullMsgId(_history->channelId(), o->at(_index + 1))); + startPlay(FullMsgId((_msgmigrated ? _migrated : _history)->channelId(), o->at(_index + 1))); + } else if (o && (_index == o->size() - 1) && _msgmigrated && _history->overviewCount[OverviewAudioDocuments] >= 0 && _history->overviewCountValue(OverviewAudioDocuments) <= _history->overview[OverviewAudioDocuments].size()) { + o = &_history->overview[OverviewAudioDocuments]; + if (!o->isEmpty()) startPlay(FullMsgId(_history->channelId(), o->at(0))); } } @@ -562,9 +587,18 @@ void PlayerWidget::updateState(SongMsgId playing, AudioPlayerState playingState, _song = playing; if (HistoryItem *item = App::histItemById(_song.msgId)) { _history = item->history(); + if (_history->peer->migrateFrom()) { + _migrated = App::history(_history->peer->migrateFrom()->id); + _msgmigrated = false; + } else if (_history->peer->migrateTo()) { + _migrated = _history; + _history = App::history(_migrated->peer->migrateTo()->id); + _msgmigrated = true; + } findCurrent(); } else { _history = 0; + _msgmigrated = false; _index = -1; } SongData *song = _song.song->song(); diff --git a/Telegram/SourceFiles/playerwidget.h b/Telegram/SourceFiles/playerwidget.h index 721b82fde..e69cd1e13 100644 --- a/Telegram/SourceFiles/playerwidget.h +++ b/Telegram/SourceFiles/playerwidget.h @@ -99,8 +99,9 @@ private: Animation _stateAnim; SongMsgId _song; + bool _msgmigrated; int32 _index; - History *_history; + History *_migrated, *_history; QRect _playRect, _prevRect, _nextRect, _playbackRect; QRect _closeRect, _volumeRect, _fullRect, _repeatRect, _infoRect; int32 _timeWidth; diff --git a/Telegram/SourceFiles/profilewidget.cpp b/Telegram/SourceFiles/profilewidget.cpp index 65076b94c..677b23b18 100644 --- a/Telegram/SourceFiles/profilewidget.cpp +++ b/Telegram/SourceFiles/profilewidget.cpp @@ -31,14 +31,15 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org #include "boxes/contactsbox.h" #include "gui/filedialog.h" -ProfileInner::ProfileInner(ProfileWidget *profile, ScrollArea *scroll, const PeerData *peer) : TWidget(0) +ProfileInner::ProfileInner(ProfileWidget *profile, ScrollArea *scroll, PeerData *peer) : TWidget(0) , _profile(profile) , _scroll(scroll) -, _peer(App::peer(peer->id)) +, _peer(peer->migrateTo() ? peer->migrateTo() : peer) , _peerUser(_peer->asUser()) , _peerChat(_peer->asChat()) , _peerChannel(_peer->asChannel()) -, _hist(App::history(peer->id)) +, _migrated(_peer->migrateFrom() ? App::history(_peer->migrateFrom()->id) : 0) +, _history(App::history(_peer->id)) , _amCreator(_peerChat ? _peerChat->amCreator() : (_peerChannel ? _peerChannel->amCreator() : false)) , _width(0) @@ -46,7 +47,7 @@ ProfileInner::ProfileInner(ProfileWidget *profile, ScrollArea *scroll, const Pee , _addToHeight(0) // profile -, _nameCache(peer->name) +, _nameCache(_peer->name) , _uploadPhoto(this, lang(lng_profile_set_group_photo), st::btnShareContact) , _addParticipant(this, lang(lng_profile_add_participant), st::btnShareContact) , _sendMessage(this, lang(lng_profile_send_message), st::btnShareContact) @@ -1133,6 +1134,7 @@ bool ProfileInner::updateMediaLinks(int32 *addToScroll) { } bool newNotAllMediaLoaded = false, changed = false, substracted = !_notAllMediaLoaded && oneWasShown; + bool notAllHistoryLoaded = false, notAllMigratedLoaded = false; bool oneIsShown = false; int32 y = _mediaButtons[OverviewPhotos]->y(); @@ -1140,9 +1142,10 @@ bool ProfileInner::updateMediaLinks(int32 *addToScroll) { for (int i = 0; i < OverviewCount; ++i) { int32 addToY = _mediaButtons[i]->height() + st::setLittleSkip; - int32 count = (_hist->overviewCount[i] > 0) ? _hist->overviewCount[i] : (_hist->overviewCount[i] == 0 ? _hist->overview[i].size() : -1); - if (count > 0) { - _mediaButtons[i]->setText(overviewLinkText(i, count)); + int32 count = _history->overviewCountValue(i), additional = _migrated ? _migrated->overviewCountValue(i) : 0; + int32 sum = (count > 0 ? count : 0) + (additional > 0 ? additional : 0); + if (sum > 0) { + _mediaButtons[i]->setText(overviewLinkText(i, sum)); if (_mediaButtons[i]->isHidden()) { _mediaButtons[i]->show(); changed = true; @@ -1165,10 +1168,14 @@ bool ProfileInner::updateMediaLinks(int32 *addToScroll) { } } if (count < 0) { - newNotAllMediaLoaded = true; + notAllHistoryLoaded = true; + } + if (additional < 0) { + notAllMigratedLoaded = true; } } } + newNotAllMediaLoaded = notAllHistoryLoaded || notAllMigratedLoaded; if (newNotAllMediaLoaded != _notAllMediaLoaded) { _notAllMediaLoaded = newNotAllMediaLoaded; changed = true; @@ -1186,7 +1193,10 @@ bool ProfileInner::updateMediaLinks(int32 *addToScroll) { } } - if (App::main()) App::main()->preloadOverviews(_peer); + if (App::main()) { + if (notAllHistoryLoaded) App::main()->preloadOverviews(_peer); + if (notAllMigratedLoaded) App::main()->preloadOverviews(_migrated->peer); + } } bool newSubstracted = !_notAllMediaLoaded && oneIsShown; if (newSubstracted && newSubstracted != substracted) { @@ -1423,7 +1433,7 @@ void ProfileInner::updateNotifySettings() { int32 ProfileInner::mediaOverviewUpdated(PeerData *peer, MediaOverviewType type) { int32 result = 0; - if (peer == _peer) { + if (peer == _peer || (_migrated && _migrated->peer == peer)) { if (updateMediaLinks(&result)) { showAll(); resizeEvent(0); @@ -1683,7 +1693,7 @@ QString ProfileInner::overviewLinkText(int32 type, int32 count) { return QString(); } -ProfileWidget::ProfileWidget(QWidget *parent, const PeerData *peer) : TWidget(parent) +ProfileWidget::ProfileWidget(QWidget *parent, PeerData *peer) : TWidget(parent) , _scroll(this, st::setScroll) , _inner(this, &_scroll, peer) , _a_show(animFunc(this, &ProfileWidget::animStep_show)) diff --git a/Telegram/SourceFiles/profilewidget.h b/Telegram/SourceFiles/profilewidget.h index 8e61161ad..3e24f8437 100644 --- a/Telegram/SourceFiles/profilewidget.h +++ b/Telegram/SourceFiles/profilewidget.h @@ -26,7 +26,7 @@ class ProfileInner : public TWidget, public RPCSender, public Animated { public: - ProfileInner(ProfileWidget *profile, ScrollArea *scroll, const PeerData *peer); + ProfileInner(ProfileWidget *profile, ScrollArea *scroll, PeerData *peer); void start(); @@ -143,7 +143,7 @@ private: UserData *_peerUser; ChatData *_peerChat; ChannelData *_peerChannel; - History *_hist; + History *_migrated, *_history; bool _amCreator; int32 _width, _left, _addToHeight; @@ -218,7 +218,7 @@ class ProfileWidget : public TWidget, public RPCSender { public: - ProfileWidget(QWidget *parent, const PeerData *peer); + ProfileWidget(QWidget *parent, PeerData *peer); void resizeEvent(QResizeEvent *e); void mousePressEvent(QMouseEvent *e); diff --git a/Telegram/SourceFiles/pspecific_wnd.cpp b/Telegram/SourceFiles/pspecific_wnd.cpp index 9a1d044c8..77cff8cad 100644 --- a/Telegram/SourceFiles/pspecific_wnd.cpp +++ b/Telegram/SourceFiles/pspecific_wnd.cpp @@ -2825,10 +2825,11 @@ bool CreateToast(PeerData *peer, int32 msgId, bool showpix, const QString &title } hr = toastNotifier->Show(toast.Get()); if (!SUCCEEDED(hr)) { - if (i->isEmpty()) toastNotifications.erase(i); + i = toastNotifications.find(peer->id); + if (i != toastNotifications.cend() && i->isEmpty()) toastNotifications.erase(i); return false; } - i->insert(msgId, toast); + toastNotifications[peer->id].insert(msgId, toast); return true; }