diff --git a/Telegram/SourceFiles/info/info.style b/Telegram/SourceFiles/info/info.style index 09fd66c6de..8a238e4310 100644 --- a/Telegram/SourceFiles/info/info.style +++ b/Telegram/SourceFiles/info/info.style @@ -150,7 +150,7 @@ infoLayerTopBar: InfoTopBar { } infoMinimalWidth: 324px; -infoDesiredWidth: 360px; +infoDesiredWidth: 430px; infoMinimalLayerMargin: 48px; infoTabs: SettingsSlider(defaultTabsSlider) { diff --git a/Telegram/SourceFiles/info/info_content_widget.cpp b/Telegram/SourceFiles/info/info_content_widget.cpp index 0f4cd1a71a..e61344deaa 100644 --- a/Telegram/SourceFiles/info/info_content_widget.cpp +++ b/Telegram/SourceFiles/info/info_content_widget.cpp @@ -57,6 +57,10 @@ ContentWidget::ContentWidget( } void ContentWidget::resizeEvent(QResizeEvent *e) { + updateControlsGeometry(); +} + +void ContentWidget::updateControlsGeometry() { auto newScrollTop = _scroll->scrollTop() + _topDelta; auto scrollGeometry = rect().marginsRemoved( QMargins(0, _scrollTopSkip, 0, 0)); @@ -113,6 +117,10 @@ Ui::RpWidget *ContentWidget::doSetInnerWidget( int desired) { inner->setVisibleTopBottom(top, bottom); }, _inner->lifetime()); + + _scrollTopSkip = scrollTopSkip; + updateControlsGeometry(); + return _inner; } diff --git a/Telegram/SourceFiles/info/info_content_widget.h b/Telegram/SourceFiles/info/info_content_widget.h index 2e66622462..fbf4c57cef 100644 --- a/Telegram/SourceFiles/info/info_content_widget.h +++ b/Telegram/SourceFiles/info/info_content_widget.h @@ -110,6 +110,7 @@ private: RpWidget *doSetInnerWidget( object_ptr inner, int scrollTopSkip); + void updateControlsGeometry(); const not_null _controller; const not_null _peer; diff --git a/Telegram/SourceFiles/info/media/info_media_inner_widget.cpp b/Telegram/SourceFiles/info/media/info_media_inner_widget.cpp index f1de1e47cd..7fa6dcb88b 100644 --- a/Telegram/SourceFiles/info/media/info_media_inner_widget.cpp +++ b/Telegram/SourceFiles/info/media/info_media_inner_widget.cpp @@ -252,9 +252,11 @@ object_ptr InnerWidget::setupList( } void InnerWidget::saveState(not_null memento) { + _list->saveState(memento); } void InnerWidget::restoreState(not_null memento) { + _list->restoreState(memento); } rpl::producer InnerWidget::selectedListValue() const { diff --git a/Telegram/SourceFiles/info/media/info_media_list_widget.cpp b/Telegram/SourceFiles/info/media/info_media_list_widget.cpp index 894198e4bd..89974fd1cf 100644 --- a/Telegram/SourceFiles/info/media/info_media_list_widget.cpp +++ b/Telegram/SourceFiles/info/media/info_media_list_widget.cpp @@ -720,6 +720,12 @@ bool ListWidget::isMyItem(not_null item) const { return (_peer == peer || _peer == peer->migrateTo()); } +bool ListWidget::isPossiblyMyId(FullMsgId fullId) const { + return (fullId.channel != 0) + ? (_peer->isChannel() && _peer->bareId() == fullId.channel) + : (!_peer->isChannel() || _peer->migrateFrom()); +} + bool ListWidget::isItemLayout( not_null item, BaseLayout *layout) const { @@ -878,6 +884,29 @@ void ListWidget::markLayoutsStale() { } } +void ListWidget::saveState(not_null memento) { + if (_universalAroundId != kDefaultAroundId) { + memento->setAroundId(computeFullId(_universalAroundId)); + memento->setIdsLimit(_idsLimit); + auto state = countScrollState(); + memento->setScrollTopItem(computeFullId(state.item)); + memento->setScrollTopShift(state.shift); + } +} + +void ListWidget::restoreState(not_null memento) { + if (auto limit = memento->idsLimit()) { + auto wasAroundId = memento->aroundId(); + if (isPossiblyMyId(wasAroundId)) { + _idsLimit = limit; + _universalAroundId = GetUniversalId(wasAroundId); + _scrollTopState.item = GetUniversalId(memento->scrollTopItem()); + _scrollTopState.shift = memento->scrollTopShift(); + refreshViewer(); + } + } +} + int ListWidget::resizeGetHeight(int newWidth) { if (newWidth > 0) { for (auto §ion : _sections) { @@ -887,7 +916,7 @@ int ListWidget::resizeGetHeight(int newWidth) { return recountHeight(); } -auto ListWidget::findItemByPoint(QPoint point) -> FoundItem { +auto ListWidget::findItemByPoint(QPoint point) const -> FoundItem { Expects(!_sections.empty()); auto sectionIt = findSectionAfterTop(point.y()); if (sectionIt == _sections.end()) { @@ -920,7 +949,7 @@ auto ListWidget::findItemDetails( auto ListWidget::foundItemInSection( const FoundItem &item, - const Section §ion) -> FoundItem { + const Section §ion) const -> FoundItem { return { item.layout, item.geometry.translated(0, section.top()), @@ -941,7 +970,7 @@ void ListWidget::checkMoveToOtherViewer() { if (width() <= 0 || visibleHeight <= 0 || _sections.empty() - || _scrollTopId) { + || _scrollTopState.item) { return; } @@ -994,34 +1023,39 @@ void ListWidget::checkMoveToOtherViewer() { } } -void ListWidget::saveScrollState() { +auto ListWidget::countScrollState() const -> ScrollTopState { if (_sections.empty()) { - _scrollTopId = 0; - _scrollTopShift = 0; - return; + return { 0, 0 }; } auto topItem = findItemByPoint({ 0, _visibleTop }); - _scrollTopId = GetUniversalId(topItem.layout); - _scrollTopShift = _visibleTop - topItem.geometry.y(); + return { + GetUniversalId(topItem.layout), + _visibleTop - topItem.geometry.y() + }; +} + +void ListWidget::saveScrollState() { + if (!_scrollTopState.item) { + _scrollTopState = countScrollState(); + } } void ListWidget::restoreScrollState() { - auto scrollTopId = base::take(_scrollTopId); - auto scrollTopShift = base::take(_scrollTopShift); - if (_sections.empty() || !scrollTopId) { + if (_sections.empty() || !_scrollTopState.item) { return; } - auto sectionIt = findSectionByItem(scrollTopId); + auto sectionIt = findSectionByItem(_scrollTopState.item); if (sectionIt == _sections.end()) { --sectionIt; } auto item = foundItemInSection( - sectionIt->findItemNearId(scrollTopId), + sectionIt->findItemNearId(_scrollTopState.item), *sectionIt); - auto newVisibleTop = item.geometry.y() + scrollTopShift; + auto newVisibleTop = item.geometry.y() + _scrollTopState.shift; if (_visibleTop != newVisibleTop) { _scrollToRequests.fire_copy(newVisibleTop); } + _scrollTopState = ScrollTopState(); } QMargins ListWidget::padding() const { diff --git a/Telegram/SourceFiles/info/media/info_media_list_widget.h b/Telegram/SourceFiles/info/media/info_media_list_widget.h index 92fa24ecd1..1a54f0e1b2 100644 --- a/Telegram/SourceFiles/info/media/info_media_list_widget.h +++ b/Telegram/SourceFiles/info/media/info_media_list_widget.h @@ -74,6 +74,9 @@ public: clearSelected(); } + void saveState(not_null memento); + void restoreState(not_null memento); + ~ListWidget(); protected: @@ -150,6 +153,10 @@ private: Touch, Other, }; + struct ScrollTopState { + UniversalMsgId item = 0; + int shift = 0; + }; void start(); int recountHeight(); @@ -160,6 +167,7 @@ private: bool isItemLayout( not_null item, BaseLayout *layout) const; + bool isPossiblyMyId(FullMsgId fullId) const; void repaintItem(const HistoryItem *item); void repaintItem(UniversalMsgId msgId); void repaintItem(const BaseLayout *item); @@ -229,13 +237,14 @@ private: std::vector
::const_iterator findSectionAfterBottom( std::vector
::const_iterator from, int bottom) const; - FoundItem findItemByPoint(QPoint point); + FoundItem findItemByPoint(QPoint point) const; base::optional findItemById(UniversalMsgId universalId); base::optional findItemDetails(BaseLayout *item); FoundItem foundItemInSection( const FoundItem &item, - const Section §ion); + const Section §ion) const; + ScrollTopState countScrollState() const; void saveScrollState(); void restoreScrollState(); @@ -268,7 +277,8 @@ private: Type _type = Type::Photo; static constexpr auto kMinimalIdsLimit = 16; - UniversalMsgId _universalAroundId = (ServerMaxMsgId - 1); + static constexpr auto kDefaultAroundId = (ServerMaxMsgId - 1); + UniversalMsgId _universalAroundId = kDefaultAroundId; int _idsLimit = kMinimalIdsLimit; SharedMediaMergedSlice _slice; @@ -277,8 +287,7 @@ private: int _visibleTop = 0; int _visibleBottom = 0; - UniversalMsgId _scrollTopId = 0; - int _scrollTopShift = 0; + ScrollTopState _scrollTopState; rpl::event_stream _scrollToRequests; MouseAction _mouseAction = MouseAction::None; diff --git a/Telegram/SourceFiles/info/media/info_media_widget.cpp b/Telegram/SourceFiles/info/media/info_media_widget.cpp index e0f85097e3..9fcc49a924 100644 --- a/Telegram/SourceFiles/info/media/info_media_widget.cpp +++ b/Telegram/SourceFiles/info/media/info_media_widget.cpp @@ -104,7 +104,6 @@ void Widget::saveState(not_null memento) { void Widget::restoreState(not_null memento) { _inner->restoreState(memento); - scrollTopRestore(memento->scrollTop()); } } // namespace Media diff --git a/Telegram/SourceFiles/info/media/info_media_widget.h b/Telegram/SourceFiles/info/media/info_media_widget.h index 918ba6fd26..f8f7866859 100644 --- a/Telegram/SourceFiles/info/media/info_media_widget.h +++ b/Telegram/SourceFiles/info/media/info_media_widget.h @@ -52,8 +52,37 @@ public: return _type; } + void setAroundId(FullMsgId aroundId) { + _aroundId = aroundId; + } + FullMsgId aroundId() const { + return _aroundId; + } + void setIdsLimit(int limit) { + _idsLimit = limit; + } + int idsLimit() const { + return _idsLimit; + } + void setScrollTopItem(FullMsgId item) { + _scrollTopItem = item; + } + FullMsgId scrollTopItem() const { + return _scrollTopItem; + } + void setScrollTopShift(int shift) { + _scrollTopShift = shift; + } + int scrollTopShift() const { + return _scrollTopShift; + } + private: Type _type = Type::Photo; + FullMsgId _aroundId; + int _idsLimit = 0; + FullMsgId _scrollTopItem; + int _scrollTopShift = 0;; };