Show hidden stories in archive.

This commit is contained in:
John Preston 2023-07-11 19:22:18 +04:00
parent 61b8aac7c4
commit 70ca3d4f1a
9 changed files with 241 additions and 159 deletions

View file

@ -3823,8 +3823,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_userpic_builder_emoji_subtitle" = "Choose sticker or emoji"; "lng_userpic_builder_emoji_subtitle" = "Choose sticker or emoji";
"lng_stories_my_name" = "My Story"; "lng_stories_my_name" = "My Story";
"lng_stories_hide_to_contacts" = "Hide"; "lng_stories_archive" = "Archive";
"lng_stories_show_in_chats" = "Show in Chats"; "lng_stories_unarchive" = "Unarchive";
"lng_stories_row_count#one" = "{count} Story"; "lng_stories_row_count#one" = "{count} Story";
"lng_stories_row_count#other" = "{count} Stories"; "lng_stories_row_count#other" = "{count} Stories";
"lng_stories_row_unread_and_one" = "{accumulated}, {user}"; "lng_stories_row_unread_and_one" = "{accumulated}, {user}";
@ -3841,8 +3841,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_stories_archive_title" = "Stories Archive"; "lng_stories_archive_title" = "Stories Archive";
"lng_stories_archive_about" = "Only you can see archived stories unless you choose to save them to your profile."; "lng_stories_archive_about" = "Only you can see archived stories unless you choose to save them to your profile.";
"lng_stories_reply_sent" = "Message Sent"; "lng_stories_reply_sent" = "Message Sent";
"lng_stories_hidden_to_contacts" = "Stories of {user} were moved to **Contacts**."; "lng_stories_hidden_to_contacts" = "Stories of {user} were moved to **Archive**.";
"lng_stories_shown_in_chats" = "Stories of {user} were moved above the **Chats List**."; "lng_stories_shown_in_chats" = "Stories of {user} were moved to the **Chats List**.";
"lng_stories_delete_one_sure" = "Are you sure you want to delete this story?"; "lng_stories_delete_one_sure" = "Are you sure you want to delete this story?";
"lng_stories_delete_sure#one" = "Are you sure you want to delete {count} story?"; "lng_stories_delete_sure#one" = "Are you sure you want to delete {count} story?";
"lng_stories_delete_sure#other" = "Are you sure you want to delete {count} stories?"; "lng_stories_delete_sure#other" = "Are you sure you want to delete {count} stories?";

View file

@ -215,12 +215,12 @@ Widget::Widget(
, _lockUnlock(_searchControls, st::dialogsLock) , _lockUnlock(_searchControls, st::dialogsLock)
, _scroll(this) , _scroll(this)
, _scrollToTop(_scroll, st::dialogsToUp) , _scrollToTop(_scroll, st::dialogsToUp)
, _stories(std::make_unique<Stories::List>( , _stories((_layout != Layout::Child)
this, ? std::make_unique<Stories::List>(
st::dialogsStoriesList, this,
Stories::ContentForSession( st::dialogsStoriesList,
&controller->session(), _storiesContents.events() | rpl::flatten_latest())
Data::StorySourcesList::NotHidden))) : nullptr)
, _searchTimer([=] { searchMessages(); }) , _searchTimer([=] { searchMessages(); })
, _singleMessageSearch(&controller->session()) { , _singleMessageSearch(&controller->session()) {
const auto makeChildListShown = [](PeerId peerId, float64 shown) { const auto makeChildListShown = [](PeerId peerId, float64 shown) {
@ -237,46 +237,6 @@ Widget::Widget(
_childListShown.value(), _childListShown.value(),
makeChildListShown))); makeChildListShown)));
_scrollToTop->raise(); _scrollToTop->raise();
rpl::combine(
_scroll->positionValue(),
_scroll->movementValue(),
_storiesExplicitExpandValue.value()
) | rpl::start_with_next([=](
Ui::ElasticScrollPosition position,
Ui::ElasticScrollMovement movement,
int explicitlyExpanded) {
const auto overscrollTop = std::max(-position.overscroll, 0);
if (overscrollTop > 0 && _storiesExplicitExpand) {
_scroll->setOverscrollDefaults(
-st::dialogsStoriesFull.height,
0,
true);
}
if (explicitlyExpanded > 0 && explicitlyExpanded < overscrollTop) {
_storiesExplicitExpandAnimation.stop();
_storiesExplicitExpand = false;
_storiesExplicitExpandValue = 0;
return;
}
const auto above = std::max(explicitlyExpanded, overscrollTop);
if (_aboveScrollAdded != above) {
_aboveScrollAdded = above;
if (_updateScrollGeometryCached) {
_updateScrollGeometryCached();
}
}
using Phase = Ui::ElasticScrollMovement;
_stories->setExpandedHeight(
_aboveScrollAdded,
(movement == Phase::Momentum || movement == Phase::Returning)
&& (explicitlyExpanded < above));
if (position.overscroll > 0
|| (position.value
> (_storiesExplicitExpandScrollTop
+ st::dialogsRowHeight))) {
storiesToggleExplicitExpand(false);
}
}, lifetime());
_inner->updated( _inner->updated(
) | rpl::start_with_next([=] { ) | rpl::start_with_next([=] {
@ -417,7 +377,9 @@ Widget::Widget(
setupMainMenuToggle(); setupMainMenuToggle();
setupShortcuts(); setupShortcuts();
setupStories(); if (_stories) {
setupStories();
}
_searchForNarrowFilters->setClickedCallback([=] { _searchForNarrowFilters->setClickedCallback([=] {
_filter->setFocusFast(); _filter->setFocusFast();
@ -609,14 +571,8 @@ void Widget::scrollToDefaultChecked(bool verytop) {
void Widget::setupScrollUpButton() { void Widget::setupScrollUpButton() {
_scrollToTop->setClickedCallback([=] { scrollToDefaultChecked(); }); _scrollToTop->setClickedCallback([=] { scrollToDefaultChecked(); });
base::install_event_filter(_scrollToTop, [=](not_null<QEvent*> event) { trackScroll(_scrollToTop);
if (event->type() != QEvent::Wheel) { trackScroll(this);
return base::EventFilterResult::Continue;
}
return _scroll->viewportEvent(event)
? base::EventFilterResult::Cancel
: base::EventFilterResult::Continue;
});
updateScrollUpVisibility(); updateScrollUpVisibility();
} }
@ -628,7 +584,7 @@ void Widget::setupMoreChatsBar() {
) | rpl::start_with_next([=](FilterId id) { ) | rpl::start_with_next([=](FilterId id) {
storiesToggleExplicitExpand(false); storiesToggleExplicitExpand(false);
if (!id && false) { // #TODO stories testing if (!id) {
_moreChatsBar = nullptr; _moreChatsBar = nullptr;
updateControlsGeometry(); updateControlsGeometry();
return; return;
@ -638,6 +594,8 @@ void Widget::setupMoreChatsBar() {
this, this,
filters->moreChatsContent(id)); filters->moreChatsContent(id));
trackScroll(_moreChatsBar->wrap());
_moreChatsBar->barClicks( _moreChatsBar->barClicks(
) | rpl::start_with_next([=] { ) | rpl::start_with_next([=] {
if (const auto missing = filters->moreChats(id) if (const auto missing = filters->moreChats(id)
@ -810,11 +768,64 @@ void Widget::setupMainMenuToggle() {
} }
void Widget::setupStories() { void Widget::setupStories() {
trackScroll(_stories.get());
_storiesContents.fire(Stories::ContentForSession(
&controller()->session(),
Data::StorySourcesList::NotHidden));
const auto currentSource = [=] {
using List = Data::StorySourcesList;
return _openedFolder ? List::Hidden : List::NotHidden;
};
rpl::combine(
_scroll->positionValue(),
_scroll->movementValue(),
_storiesExplicitExpandValue.value()
) | rpl::start_with_next([=](
Ui::ElasticScrollPosition position,
Ui::ElasticScrollMovement movement,
int explicitlyExpanded) {
if (_stories->isHidden()) {
return;
}
const auto overscrollTop = std::max(-position.overscroll, 0);
if (overscrollTop > 0 && _storiesExplicitExpand) {
_scroll->setOverscrollDefaults(
-st::dialogsStoriesFull.height,
0,
true);
}
if (explicitlyExpanded > 0 && explicitlyExpanded < overscrollTop) {
_storiesExplicitExpandAnimation.stop();
_storiesExplicitExpand = false;
_storiesExplicitExpandValue = 0;
return;
}
const auto above = std::max(explicitlyExpanded, overscrollTop);
if (_aboveScrollAdded != above) {
_aboveScrollAdded = above;
if (_updateScrollGeometryCached) {
_updateScrollGeometryCached();
}
}
using Phase = Ui::ElasticScrollMovement;
_stories->setExpandedHeight(
_aboveScrollAdded,
(movement == Phase::Momentum || movement == Phase::Returning)
&& (explicitlyExpanded < above));
if (position.overscroll > 0
|| (position.value
> (_storiesExplicitExpandScrollTop
+ st::dialogsRowHeight))) {
storiesToggleExplicitExpand(false);
}
}, lifetime());
_stories->clicks( _stories->clicks(
) | rpl::start_with_next([=](uint64 id) { ) | rpl::start_with_next([=](uint64 id) {
controller()->openPeerStories( controller()->openPeerStories(PeerId(int64(id)), currentSource());
PeerId(int64(id)),
Data::StorySourcesList::NotHidden);
}, lifetime()); }, lifetime());
_stories->showMenuRequests( _stories->showMenuRequests(
@ -824,8 +835,7 @@ void Widget::setupStories() {
_stories->loadMoreRequests( _stories->loadMoreRequests(
) | rpl::start_with_next([=] { ) | rpl::start_with_next([=] {
session().data().stories().loadMore( session().data().stories().loadMore(currentSource());
Data::StorySourcesList::NotHidden);
}, lifetime()); }, lifetime());
_stories->toggleExpandedRequests( _stories->toggleExpandedRequests(
@ -860,6 +870,20 @@ void Widget::storiesToggleExplicitExpand(bool expand) {
}, expand ? 0 : height, expand ? height : 0, duration, anim::sineInOut); }, expand ? 0 : height, expand ? height : 0, duration, anim::sineInOut);
} }
void Widget::trackScroll(not_null<Ui::RpWidget*> widget) {
widget->events(
) | rpl::start_with_next([=](not_null<QEvent*> e) {
const auto type = e->type();
if (type == QEvent::TouchBegin
|| type == QEvent::TouchUpdate
|| type == QEvent::TouchEnd
|| type == QEvent::TouchCancel
|| type == QEvent::Wheel) {
_scroll->viewportEvent(e);
}
}, widget->lifetime());
}
void Widget::setupShortcuts() { void Widget::setupShortcuts() {
Shortcuts::Requests( Shortcuts::Requests(
) | rpl::filter([=] { ) | rpl::filter([=] {
@ -902,6 +926,7 @@ void Widget::fullSearchRefreshOn(rpl::producer<> events) {
void Widget::updateControlsVisibility(bool fast) { void Widget::updateControlsVisibility(bool fast) {
updateLoadMoreChatsVisibility(); updateLoadMoreChatsVisibility();
_scroll->show(); _scroll->show();
updateStoriesVisibility();
if ((_openedFolder || _openedForum) && _filter->hasFocus()) { if ((_openedFolder || _openedForum) && _filter->hasFocus()) {
setInnerFocus(); setInnerFocus();
} }
@ -1002,9 +1027,16 @@ void Widget::changeOpenedFolder(Data::Folder *folder, anim::type animated) {
cancelSearch(); cancelSearch();
closeChildList(anim::type::instant); closeChildList(anim::type::instant);
controller()->closeForum(); controller()->closeForum();
const auto was = (_openedFolder != nullptr);
_openedFolder = folder; _openedFolder = folder;
_inner->changeOpenedFolder(folder); _inner->changeOpenedFolder(folder);
storiesToggleExplicitExpand(false); storiesToggleExplicitExpand(false);
if (was != (_openedFolder != nullptr)) {
using List = Data::StorySourcesList;
_storiesContents.fire(Stories::ContentForSession(
&controller()->session(),
folder ? List::Hidden : List::NotHidden));
}
}, (folder != nullptr), animated); }, (folder != nullptr), animated);
} }
@ -1019,6 +1051,7 @@ void Widget::changeOpenedForum(Data::Forum *forum, anim::type animated) {
_api.request(base::take(_topicSearchRequest)).cancel(); _api.request(base::take(_topicSearchRequest)).cancel();
_inner->changeOpenedForum(forum); _inner->changeOpenedForum(forum);
storiesToggleExplicitExpand(false); storiesToggleExplicitExpand(false);
updateStoriesVisibility();
}, (forum != nullptr), animated); }, (forum != nullptr), animated);
} }
@ -1032,6 +1065,9 @@ void Widget::refreshTopBars() {
if (_openedFolder || _openedForum) { if (_openedFolder || _openedForum) {
if (!_subsectionTopBar) { if (!_subsectionTopBar) {
_subsectionTopBar.create(this, controller()); _subsectionTopBar.create(this, controller());
if (_stories) {
_stories->raise();
}
_subsectionTopBar->searchCancelled( _subsectionTopBar->searchCancelled(
) | rpl::start_with_next([=] { ) | rpl::start_with_next([=] {
escape(); escape();
@ -1306,6 +1342,7 @@ void Widget::startWidthAnimation() {
_widthAnimationCache = Ui::PixmapFromImage(std::move(image)); _widthAnimationCache = Ui::PixmapFromImage(std::move(image));
_scroll->setGeometry(scrollGeometry); _scroll->setGeometry(scrollGeometry);
_scroll->hide(); _scroll->hide();
updateStoriesVisibility();
} }
void Widget::stopWidthAnimation() { void Widget::stopWidthAnimation() {
@ -1313,9 +1350,41 @@ void Widget::stopWidthAnimation() {
if (!_showAnimation) { if (!_showAnimation) {
_scroll->show(); _scroll->show();
} }
updateStoriesVisibility();
update(); update();
} }
void Widget::updateStoriesVisibility() {
if (!_stories) {
return;
}
const auto hidden = (_showAnimation != nullptr)
|| _openedForum
|| !_widthAnimationCache.isNull()
|| _childList
|| !_filter->getLastText().isEmpty()
|| _searchInChat;
if (_stories->isHidden() != hidden) {
_stories->setVisible(!hidden);
using Type = Ui::ElasticScroll::OverscrollType;
if (hidden) {
_scroll->setOverscrollDefaults(0, 0);
_scroll->setOverscrollTypes(Type::Real, Type::Real);
if (_scroll->position().overscroll < 0) {
_scroll->scrollToY(0);
}
} else {
_scroll->setOverscrollDefaults(0, 0);
_scroll->setOverscrollTypes(Type::Virtual, Type::Real);
_storiesExplicitExpandValue.force_assign(
_storiesExplicitExpandValue.current());
}
if (_aboveScrollAdded > 0 && _updateScrollGeometryCached) {
_updateScrollGeometryCached();
}
}
}
void Widget::showFast() { void Widget::showFast() {
if (isHidden()) { if (isHidden()) {
_inner->clearSelection(); _inner->clearSelection();
@ -1358,6 +1427,9 @@ void Widget::startSlideAnimation(
QPixmap newContentCache, QPixmap newContentCache,
Window::SlideDirection direction) { Window::SlideDirection direction) {
_scroll->hide(); _scroll->hide();
if (_stories) {
_stories->hide();
}
_searchControls->hide(); _searchControls->hide();
if (_subsectionTopBar) { if (_subsectionTopBar) {
_subsectionTopBar->hide(); _subsectionTopBar->hide();
@ -2166,6 +2238,7 @@ void Widget::applyFilterUpdate(bool force) {
return; return;
} }
updateStoriesVisibility();
const auto filterText = currentSearchQuery(); const auto filterText = currentSearchQuery();
_inner->applyFilterUpdate(filterText, force); _inner->applyFilterUpdate(filterText, force);
if (filterText.isEmpty() && !_searchFromAuthor) { if (filterText.isEmpty() && !_searchFromAuthor) {
@ -2319,6 +2392,7 @@ void Widget::closeChildList(anim::type animated) {
} else { } else {
_childListShadow = nullptr; _childListShadow = nullptr;
} }
updateStoriesVisibility();
} }
void Widget::searchInChat(Key chat) { void Widget::searchInChat(Key chat) {
@ -2372,6 +2446,7 @@ bool Widget::setSearchInChat(Key chat, PeerData *from) {
_searchInChat = chat; _searchInChat = chat;
controller()->searchInChat = _searchInChat; controller()->searchInChat = _searchInChat;
updateJumpToDateVisibility(); updateJumpToDateVisibility();
updateStoriesVisibility();
} }
if (searchFromUpdated) { if (searchFromUpdated) {
updateSearchFromVisibility(); updateSearchFromVisibility();
@ -2614,9 +2689,11 @@ void Widget::updateControlsGeometry() {
const auto storiesHeight = 2 * st::dialogsStories.photoTop const auto storiesHeight = 2 * st::dialogsStories.photoTop
+ st::dialogsStories.photo; + st::dialogsStories.photo;
const auto added = (st::dialogsFilter.heightMin - storiesHeight) / 2; const auto added = (st::dialogsFilter.heightMin - storiesHeight) / 2;
_stories->setLayoutConstraints( if (_stories) {
{ filterLeft + filterWidth, filterTop + added }, _stories->setLayoutConstraints(
{ 0, expandedStoriesTop, barw, st::dialogsStoriesFull.height }); { filterLeft + filterWidth, filterTop + added },
{ 0, expandedStoriesTop, barw, st::dialogsStoriesFull.height });
}
if (_forumTopShadow) { if (_forumTopShadow) {
_forumTopShadow->setGeometry( _forumTopShadow->setGeometry(
0, 0,
@ -2650,43 +2727,49 @@ void Widget::updateControlsGeometry() {
? wasScrollTop ? wasScrollTop
: (wasScrollTop + _topDelta); : (wasScrollTop + _topDelta);
const auto scrollw = _childList ? _narrowWidth : barw; const auto scrollWidth = _childList ? _narrowWidth : barw;
if (_moreChatsBar) {
_moreChatsBar->resizeToWidth(barw);
}
if (_forumGroupCallBar) {
_forumGroupCallBar->resizeToWidth(barw);
}
if (_forumRequestsBar) {
_forumRequestsBar->resizeToWidth(barw);
}
_updateScrollGeometryCached = [=] { _updateScrollGeometryCached = [=] {
const auto moreChatsBarTop = expandedStoriesTop + _aboveScrollAdded; const auto moreChatsBarTop = expandedStoriesTop
+ ((!_stories || _stories->isHidden()) ? 0 : _aboveScrollAdded);
if (_moreChatsBar) { if (_moreChatsBar) {
_moreChatsBar->move(0, moreChatsBarTop); _moreChatsBar->move(0, moreChatsBarTop);
_moreChatsBar->resizeToWidth(barw);
} }
const auto forumGroupCallTop = moreChatsBarTop const auto forumGroupCallTop = moreChatsBarTop
+ (_moreChatsBar ? _moreChatsBar->height() : 0); + (_moreChatsBar ? _moreChatsBar->height() : 0);
if (_forumGroupCallBar) { if (_forumGroupCallBar) {
_forumGroupCallBar->move(0, forumGroupCallTop); _forumGroupCallBar->move(0, forumGroupCallTop);
_forumGroupCallBar->resizeToWidth(barw);
} }
const auto forumRequestsTop = forumGroupCallTop const auto forumRequestsTop = forumGroupCallTop
+ (_forumGroupCallBar ? _forumGroupCallBar->height() : 0); + (_forumGroupCallBar ? _forumGroupCallBar->height() : 0);
if (_forumRequestsBar) { if (_forumRequestsBar) {
_forumRequestsBar->move(0, forumRequestsTop); _forumRequestsBar->move(0, forumRequestsTop);
_forumRequestsBar->resizeToWidth(barw);
} }
const auto forumReportTop = forumRequestsTop const auto forumReportTop = forumRequestsTop
+ (_forumRequestsBar ? _forumRequestsBar->height() : 0); + (_forumRequestsBar ? _forumRequestsBar->height() : 0);
if (_forumReportBar) { if (_forumReportBar) {
_forumReportBar->bar().move(0, forumReportTop); _forumReportBar->bar().move(0, forumReportTop);
} }
auto scrollTop = forumReportTop const auto scrollTop = forumReportTop
+ (_forumReportBar ? _forumReportBar->bar().height() : 0); + (_forumReportBar ? _forumReportBar->bar().height() : 0);
auto scrollHeight = height() - scrollTop; const auto scrollHeight = height() - scrollTop;
const auto wasScrollHeight = _scroll->height(); const auto wasScrollHeight = _scroll->height();
_scroll->setGeometry(0, scrollTop, scrollw, scrollHeight); _scroll->setGeometry(0, scrollTop, scrollWidth, scrollHeight);
if (scrollHeight != wasScrollHeight) { if (scrollHeight != wasScrollHeight) {
controller()->floatPlayerAreaUpdated(); controller()->floatPlayerAreaUpdated();
} }
}; };
_updateScrollGeometryCached(); _updateScrollGeometryCached();
_inner->resize(scrollw, _inner->height()); _inner->resize(scrollWidth, _inner->height());
_inner->setNarrowRatio(narrowRatio); _inner->setNarrowRatio(narrowRatio);
if (newScrollTop != wasScrollTop) { if (newScrollTop != wasScrollTop) {
_scroll->scrollToY(newScrollTop); _scroll->scrollToY(newScrollTop);
@ -2698,7 +2781,7 @@ void Widget::updateControlsGeometry() {
} }
if (_childList) { if (_childList) {
const auto childw = std::max(_narrowWidth, width() - scrollw); const auto childw = std::max(_narrowWidth, width() - scrollWidth);
const auto childh = _scroll->y() + _scroll->height(); const auto childh = _scroll->y() + _scroll->height();
const auto childx = width() - childw; const auto childx = width() - childw;
_childList->setGeometryWithTopMoved( _childList->setGeometryWithTopMoved(

View file

@ -58,6 +58,7 @@ struct SectionShow;
namespace Dialogs::Stories { namespace Dialogs::Stories {
class List; class List;
struct Content;
} // namespace Dialogs::Stories } // namespace Dialogs::Stories
namespace Dialogs { namespace Dialogs {
@ -168,6 +169,7 @@ private:
void setupShortcuts(); void setupShortcuts();
void setupStories(); void setupStories();
void storiesToggleExplicitExpand(bool expand); void storiesToggleExplicitExpand(bool expand);
void trackScroll(not_null<Ui::RpWidget*> widget);
[[nodiscard]] bool searchForPeersRequired(const QString &query) const; [[nodiscard]] bool searchForPeersRequired(const QString &query) const;
[[nodiscard]] bool searchForTopicsRequired(const QString &query) const; [[nodiscard]] bool searchForTopicsRequired(const QString &query) const;
bool setSearchInChat(Key chat, PeerData *from = nullptr); bool setSearchInChat(Key chat, PeerData *from = nullptr);
@ -179,6 +181,7 @@ private:
void updateControlsVisibility(bool fast = false); void updateControlsVisibility(bool fast = false);
void updateLockUnlockVisibility(); void updateLockUnlockVisibility();
void updateLoadMoreChatsVisibility(); void updateLoadMoreChatsVisibility();
void updateStoriesVisibility();
void updateJumpToDateVisibility(bool fast = false); void updateJumpToDateVisibility(bool fast = false);
void updateSearchFromVisibility(bool fast = false); void updateSearchFromVisibility(bool fast = false);
void updateControlsGeometry(); void updateControlsGeometry();
@ -268,6 +271,14 @@ private:
bool _scrollToTopIsShown = false; bool _scrollToTopIsShown = false;
bool _forumSearchRequested = false; bool _forumSearchRequested = false;
Data::Folder *_openedFolder = nullptr;
Data::Forum *_openedForum = nullptr;
Dialogs::Key _searchInChat;
History *_searchInMigrated = nullptr;
PeerData *_searchFromAuthor = nullptr;
QString _lastFilterText;
rpl::event_stream<rpl::producer<Stories::Content>> _storiesContents;
Fn<void()> _updateScrollGeometryCached; Fn<void()> _updateScrollGeometryCached;
std::unique_ptr<Stories::List> _stories; std::unique_ptr<Stories::List> _stories;
Ui::Animations::Simple _storiesExplicitExpandAnimation; Ui::Animations::Simple _storiesExplicitExpandAnimation;
@ -276,13 +287,6 @@ private:
int _aboveScrollAdded = 0; int _aboveScrollAdded = 0;
bool _storiesExplicitExpand = false; bool _storiesExplicitExpand = false;
Data::Folder *_openedFolder = nullptr;
Data::Forum *_openedForum = nullptr;
Dialogs::Key _searchInChat;
History *_searchInMigrated = nullptr;
PeerData *_searchFromAuthor = nullptr;
QString _lastFilterText;
base::Timer _searchTimer; base::Timer _searchTimer;
QString _peerSearchQuery; QString _peerSearchQuery;

View file

@ -503,14 +503,14 @@ void FillSourceMenu(
controller->uiShow()); controller->uiShow());
}; };
if (in(Data::StorySourcesList::NotHidden)) { if (in(Data::StorySourcesList::NotHidden)) {
add(tr::lng_stories_hide_to_contacts(tr::now), [=] { add(tr::lng_stories_archive(tr::now), [=] {
toggle(false); toggle(false);
}, &st::menuIconCancel); }, &st::menuIconArchive);
} }
if (in(Data::StorySourcesList::Hidden)) { if (in(Data::StorySourcesList::Hidden)) {
add(tr::lng_stories_show_in_chats(tr::now), [=] { add(tr::lng_stories_unarchive(tr::now), [=] {
toggle(true); toggle(true);
}, &st::menuIconStoriesToChats); }, &st::menuIconUnarchive);
} }
} }
} }

View file

@ -21,8 +21,8 @@ namespace {
constexpr auto kSmallThumbsShown = 3; constexpr auto kSmallThumbsShown = 3;
constexpr auto kSummaryExpandLeft = 1; constexpr auto kSummaryExpandLeft = 1;
constexpr auto kPreloadPages = 2; constexpr auto kPreloadPages = 2;
constexpr auto kExpandAfterRatio = 0.85; constexpr auto kExpandAfterRatio = 0.72;
constexpr auto kCollapseAfterRatio = 0.72; constexpr auto kCollapseAfterRatio = 0.68;
constexpr auto kFrictionRatio = 0.15; constexpr auto kFrictionRatio = 0.15;
constexpr auto kExpandCatchUpDuration = crl::time(200); constexpr auto kExpandCatchUpDuration = crl::time(200);
@ -66,7 +66,6 @@ List::List(
showContent(std::move(content)); showContent(std::move(content));
}, lifetime()); }, lifetime());
_shownAnimation.stop();
setMouseTracking(true); setMouseTracking(true);
resize(0, _data.empty() ? 0 : st.full.height); resize(0, _data.empty() ? 0 : st.full.height);
} }
@ -76,18 +75,13 @@ void List::showContent(Content &&content) {
return; return;
} }
if (content.elements.empty()) { if (content.elements.empty()) {
_hidingData = base::take(_data); _data = {};
if (!_hidingData.empty()) { _empty = true;
toggleAnimated(false);
}
return; return;
} }
const auto hidden = _content.elements.empty(); const auto wasCount = int(_data.items.size());
const auto wasCount = int((hidden ? _hidingData : _data).items.size());
_content = std::move(content); _content = std::move(content);
auto items = base::take( auto items = base::take(_data.items);
_data.items.empty() ? _hidingData.items : _data.items);
_hidingData = {};
_data.items.reserve(_content.elements.size()); _data.items.reserve(_content.elements.size());
for (const auto &element : _content.elements) { for (const auto &element : _content.elements) {
const auto id = element.id; const auto id = element.id;
@ -117,8 +111,8 @@ void List::showContent(Content &&content) {
updateScrollMax(); updateScrollMax();
updateSummary(_data); updateSummary(_data);
update(); update();
if (hidden) { if (!wasCount) {
toggleAnimated(true); _empty = false;
} }
} }
@ -204,24 +198,6 @@ void List::updateSummary(Data &data) {
Populate(_st.small, data.summaries); Populate(_st.small, data.summaries);
} }
void List::toggleAnimated(bool shown) {
_shownAnimation.start(
[=] { updateHeight(); },
shown ? 0. : 1.,
shown ? 1. : 0.,
st::slideWrapDuration);
}
void List::updateHeight() {
const auto shown = _shownAnimation.value(_data.empty() ? 0. : 1.);
resize(
width(),
anim::interpolate(0, _st.full.height, shown));
if (_data.empty() && shown == 0.) {
_hidingData = {};
}
}
void List::updateScrollMax() { void List::updateScrollMax() {
const auto &full = _st.full; const auto &full = _st.full;
const auto singleFull = full.photoLeft * 2 + full.photo; const auto singleFull = full.photoLeft * 2 + full.photo;
@ -256,7 +232,7 @@ void List::requestExpanded(bool expanded) {
if (_expanded != expanded) { if (_expanded != expanded) {
_expanded = expanded; _expanded = expanded;
_expandedAnimation.start( _expandedAnimation.start(
[=] { update(); }, [=] { checkForFullState(); update(); },
_expanded ? 0. : 1., _expanded ? 0. : 1.,
_expanded ? 1. : 0., _expanded ? 1. : 0.,
st::slideWrapDuration, st::slideWrapDuration,
@ -308,15 +284,14 @@ List::Layout List::computeLayout() {
const auto lerp = [&](float64 a, float64 b) { const auto lerp = [&](float64 a, float64 b) {
return a + (b - a) * ratio; return a + (b - a) * ratio;
}; };
auto &rendering = _data.empty() ? _hidingData : _data;
const auto singleFull = full.photoLeft * 2 + full.photo; const auto singleFull = full.photoLeft * 2 + full.photo;
const auto itemsCount = int(rendering.items.size()); const auto itemsCount = int(_data.items.size());
const auto narrowWidth = st::defaultDialogRow.padding.left() const auto narrowWidth = st::defaultDialogRow.padding.left()
+ st::defaultDialogRow.photoSize + st::defaultDialogRow.photoSize
+ st::defaultDialogRow.padding.left(); + st::defaultDialogRow.padding.left();
const auto narrow = false;// (width() <= narrowWidth); const auto narrow = false;// (width() <= narrowWidth);
const auto smallSkip = (itemsCount > 1 const auto smallSkip = (itemsCount > 1
&& rendering.items[0].element.skipSmall) && _data.items[0].element.skipSmall)
? 1 ? 1
: 0; : 0;
const auto smallCount = std::min( const auto smallCount = std::min(
@ -378,7 +353,6 @@ void List::paintEvent(QPaintEvent *e) {
const auto elerp = [&](float64 a, float64 b) { const auto elerp = [&](float64 a, float64 b) {
return a + (b - a) * expandRatio; return a + (b - a) * expandRatio;
}; };
auto &rendering = _data.empty() ? _hidingData : _data;
const auto line = elerp(st.lineTwice, full.lineTwice) / 2.; const auto line = elerp(st.lineTwice, full.lineTwice) / 2.;
const auto lineRead = elerp(st.lineReadTwice, full.lineReadTwice) / 2.; const auto lineRead = elerp(st.lineReadTwice, full.lineReadTwice) / 2.;
const auto photoTopSmall = st.photoTop; const auto photoTopSmall = st.photoTop;
@ -389,7 +363,8 @@ void List::paintEvent(QPaintEvent *e) {
- (st.photoTop + (st.photo / 2.)) - (st.photoTop + (st.photo / 2.))
+ (photoTop + (photo / 2.)); + (photoTop + (photo / 2.));
const auto nameScale = _lastRatio; const auto nameScale = _lastRatio;
const auto nameTop = nameScale * full.nameTop; const auto nameTop = full.nameTop
+ (photoTop + photo - full.photoTop - full.photo);
const auto nameWidth = nameScale * AvailableNameWidth(_st); const auto nameWidth = nameScale * AvailableNameWidth(_st);
const auto nameHeight = nameScale * full.nameStyle.font->height; const auto nameHeight = nameScale * full.nameStyle.font->height;
const auto nameLeft = layout.photoLeft + (photo - nameWidth) / 2.; const auto nameLeft = layout.photoLeft + (photo - nameWidth) / 2.;
@ -402,11 +377,11 @@ void List::paintEvent(QPaintEvent *e) {
const auto left = anim::interpolate( const auto left = anim::interpolate(
_changingGeometryFrom.x(), _changingGeometryFrom.x(),
_geometryFull.x(), _geometryFull.x(),
layout.expandedRatio); layout.ratio);
const auto top = anim::interpolate( const auto top = anim::interpolate(
_changingGeometryFrom.y(), _changingGeometryFrom.y(),
_geometryFull.y(), _geometryFull.y(),
layout.expandedRatio); layout.ratio);
p.translate(QPoint(left, top) - pos()); p.translate(QPoint(left, top) - pos());
} }
@ -433,18 +408,19 @@ void List::paintEvent(QPaintEvent *e) {
const auto lookup = [&](int index) { const auto lookup = [&](int index) {
const auto indexSmall = layout.startIndexSmall + index; const auto indexSmall = layout.startIndexSmall + index;
const auto indexFull = layout.startIndexFull + index; const auto indexFull = layout.startIndexFull + index;
const auto k = (photoTop - photoTopSmall);
const auto ySmall = photoTopSmall const auto ySmall = photoTopSmall
+ ((indexSmall - layout.smallSkip + 1) + ((photoTop - photoTopSmall)
* (photoTop - photoTopSmall) / 3.); * (kSmallThumbsShown - indexSmall + layout.smallSkip) / 0.5);
const auto y = elerp(ySmall, photoTop); const auto y = elerp(ySmall, photoTop);
const auto small = (drawSmall const auto small = (drawSmall
&& indexSmall < layout.endIndexSmall && indexSmall < layout.endIndexSmall
&& indexSmall >= layout.smallSkip) && indexSmall >= layout.smallSkip)
? &rendering.items[indexSmall] ? &_data.items[indexSmall]
: nullptr; : nullptr;
const auto full = (drawFull && indexFull < layout.endIndexFull) const auto full = (drawFull && indexFull < layout.endIndexFull)
? &rendering.items[indexFull] ? &_data.items[indexFull]
: nullptr; : nullptr;
const auto x = layout.left + layout.single * index; const auto x = layout.left + layout.single * index;
return Single{ x, indexSmall, small, indexFull, full, y }; return Single{ x, indexSmall, small, indexFull, full, y };
@ -556,9 +532,16 @@ void List::paintEvent(QPaintEvent *e) {
// White circle with possible read gray line. // White circle with possible read gray line.
const auto hasReadLine = (itemFull && !fullUnread); const auto hasReadLine = (itemFull && !fullUnread);
p.setOpacity((small && itemFull)
? 1.
: small
? (1. - expandRatio)
: expandRatio);
if (hasReadLine) { if (hasReadLine) {
auto color = st::dialogsUnreadBgMuted->c; auto color = st::dialogsUnreadBgMuted->c;
color.setAlphaF(color.alphaF() * expandRatio); if (small) {
color.setAlphaF(color.alphaF() * expandRatio);
}
auto pen = QPen(color); auto pen = QPen(color);
pen.setWidthF(lineRead); pen.setWidthF(lineRead);
p.setPen(pen); p.setPen(pen);
@ -601,7 +584,7 @@ void List::paintEvent(QPaintEvent *e) {
p.setOpacity(1.); p.setOpacity(1.);
}); });
paintSummary(p, rendering, summaryTop, ratio); paintSummary(p, _data, summaryTop, ratio);
} }
void List::validateThumbnail(not_null<Item*> item) { void List::validateThumbnail(not_null<Item*> item) {
@ -729,7 +712,7 @@ void List::paintSummary(
void List::wheelEvent(QWheelEvent *e) { void List::wheelEvent(QWheelEvent *e) {
const auto horizontal = (e->angleDelta().x() != 0); const auto horizontal = (e->angleDelta().x() != 0);
if (!horizontal) { if (!horizontal || _state == State::Small) {
e->ignore(); e->ignore();
return; return;
} }
@ -757,6 +740,10 @@ void List::wheelEvent(QWheelEvent *e) {
void List::mousePressEvent(QMouseEvent *e) { void List::mousePressEvent(QMouseEvent *e) {
if (e->button() != Qt::LeftButton) { if (e->button() != Qt::LeftButton) {
return; return;
} else if (_state == State::Small) {
requestExpanded(true);
} else if (_state != State::Full) {
return;
} }
_lastMousePosition = e->globalPos(); _lastMousePosition = e->globalPos();
updateSelected(); updateSelected();
@ -834,25 +821,28 @@ void List::setExpandedHeight(int height, bool momentum) {
_expandIgnored = false; _expandIgnored = false;
_expandCatchUpAnimation.start([=] { _expandCatchUpAnimation.start([=] {
update(); update();
if (!_expandCatchUpAnimation.animating() checkForFullState();
&& _lastExpandedHeight == _st.full.height) {
setState(State::Full);
}
}, 0., 1., kExpandCatchUpDuration); }, 0., 1., kExpandCatchUpDuration);
} else if (!height && _expandCatchUpAnimation.animating()) { } else if (!height && _expandCatchUpAnimation.animating()) {
_expandCatchUpAnimation.stop(); _expandCatchUpAnimation.stop();
} }
_lastExpandedHeight = height; _lastExpandedHeight = height;
setState(!height if (!checkForFullState()) {
? State::Small setState(!height ? State::Small : State::Changing);
: (height < _st.full.height }
|| _expandCatchUpAnimation.animating()
|| _expandedAnimation.animating())
? State::Changing
: State::Full);
update(); update();
} }
bool List::checkForFullState() {
if (_expandCatchUpAnimation.animating()
|| _expandedAnimation.animating()
|| _lastExpandedHeight < _st.full.height) {
return false;
}
setState(State::Full);
return true;
}
void List::setLayoutConstraints(QPoint topRightSmall, QRect geometryFull) { void List::setLayoutConstraints(QPoint topRightSmall, QRect geometryFull) {
_topRightSmall = topRightSmall; _topRightSmall = topRightSmall;
_geometryFull = geometryFull; _geometryFull = geometryFull;
@ -875,7 +865,9 @@ void List::updateGeometry() {
QRect List::countSmallGeometry() const { QRect List::countSmallGeometry() const {
const auto &st = _st.small; const auto &st = _st.small;
const auto layout = const_cast<List*>(this)->computeLayout(); const auto layout = const_cast<List*>(this)->computeLayout();
const auto count = layout.endIndexSmall - layout.startIndexSmall; const auto count = layout.endIndexSmall
- layout.startIndexSmall
- layout.smallSkip;
const auto width = st.left const auto width = st.left
+ st.photoLeft + st.photoLeft
+ st.photo + (count - 1) * st.shift + st.photo + (count - 1) * st.shift
@ -893,9 +885,6 @@ void List::setState(State state) {
return; return;
} }
_state = state; _state = state;
setAttribute(
Qt::WA_TransparentForMouseEvents,
state == State::Changing);
updateGeometry(); updateGeometry();
} }

View file

@ -68,6 +68,12 @@ public:
void setExpandedHeight(int height, bool momentum = false); void setExpandedHeight(int height, bool momentum = false);
void setLayoutConstraints(QPoint topRightSmall, QRect geometryFull); void setLayoutConstraints(QPoint topRightSmall, QRect geometryFull);
[[nodiscard]] bool empty() const {
return _empty.current();
}
[[nodiscard]] rpl::producer<bool> emptyValue() const {
return _empty.value();
}
[[nodiscard]] rpl::producer<uint64> clicks() const; [[nodiscard]] rpl::producer<uint64> clicks() const;
[[nodiscard]] rpl::producer<ShowMenuRequest> showMenuRequests() const; [[nodiscard]] rpl::producer<ShowMenuRequest> showMenuRequests() const;
[[nodiscard]] rpl::producer<bool> toggleExpandedRequests() const; [[nodiscard]] rpl::producer<bool> toggleExpandedRequests() const;
@ -153,12 +159,11 @@ private:
void checkLoadMore(); void checkLoadMore();
void requestExpanded(bool expanded); void requestExpanded(bool expanded);
bool checkForFullState();
void setState(State state); void setState(State state);
void updateGeometry(); void updateGeometry();
[[nodiscard]] QRect countSmallGeometry() const; [[nodiscard]] QRect countSmallGeometry() const;
void updateExpanding(int expandingHeight, int expandedHeight); void updateExpanding(int expandingHeight, int expandedHeight);
void updateHeight();
void toggleAnimated(bool shown);
void paintSummary( void paintSummary(
QPainter &p, QPainter &p,
Data &data, Data &data,
@ -170,7 +175,6 @@ private:
const style::DialogsStoriesList &_st; const style::DialogsStoriesList &_st;
Content _content; Content _content;
Data _data; Data _data;
Data _hidingData;
rpl::event_stream<uint64> _clicks; rpl::event_stream<uint64> _clicks;
rpl::event_stream<ShowMenuRequest> _showMenuRequests; rpl::event_stream<ShowMenuRequest> _showMenuRequests;
rpl::event_stream<bool> _toggleExpandedRequests; rpl::event_stream<bool> _toggleExpandedRequests;
@ -181,8 +185,7 @@ private:
QRect _geometryFull; QRect _geometryFull;
QRect _changingGeometryFrom; QRect _changingGeometryFrom;
State _state = State::Small; State _state = State::Small;
rpl::variable<bool> _empty = true;
Ui::Animations::Simple _shownAnimation;
QPoint _lastMousePosition; QPoint _lastMousePosition;
std::optional<QPoint> _mouseDownPosition; std::optional<QPoint> _mouseDownPosition;

View file

@ -31,6 +31,10 @@ public:
rpl::producer<MoreChatsBarContent> content); rpl::producer<MoreChatsBarContent> content);
~MoreChatsBar(); ~MoreChatsBar();
[[nodiscard]] not_null<RpWidget*> wrap() {
return &_wrap;
}
void show(); void show();
void hide(); void hide();
void raise(); void raise();

View file

@ -112,7 +112,6 @@ menuIconArchiveOpen: icon {{ "menu/archive_open", menuIconColor }};
menuIconGroups: icon {{ "menu/groups", menuIconColor }}; menuIconGroups: icon {{ "menu/groups", menuIconColor }};
menuIconSavedMessages: icon {{ "menu/saved_messages", menuIconColor }}; menuIconSavedMessages: icon {{ "menu/saved_messages", menuIconColor }};
menuIconNightMode: icon {{ "menu/night_mode", menuIconColor }}; menuIconNightMode: icon {{ "menu/night_mode", menuIconColor }};
menuIconStoriesToChats: icon {{ "menu/stories_to_chats", menuIconColor }};
menuIconTTLAny: icon {{ "menu/auto_delete_plain", menuIconColor }}; menuIconTTLAny: icon {{ "menu/auto_delete_plain", menuIconColor }};
menuIconTTLAnyTextPosition: point(11px, 22px); menuIconTTLAnyTextPosition: point(11px, 22px);

@ -1 +1 @@
Subproject commit 763b3a37c34fd7819f9d553b94387c4fe16554ff Subproject commit 427fc4c8f7c8b92cca900e0270718f83fcb16e35