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_stories_my_name" = "My Story";
"lng_stories_hide_to_contacts" = "Hide";
"lng_stories_show_in_chats" = "Show in Chats";
"lng_stories_archive" = "Archive";
"lng_stories_unarchive" = "Unarchive";
"lng_stories_row_count#one" = "{count} Story";
"lng_stories_row_count#other" = "{count} Stories";
"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_about" = "Only you can see archived stories unless you choose to save them to your profile.";
"lng_stories_reply_sent" = "Message Sent";
"lng_stories_hidden_to_contacts" = "Stories of {user} were moved to **Contacts**.";
"lng_stories_shown_in_chats" = "Stories of {user} were moved above the **Chats List**.";
"lng_stories_hidden_to_contacts" = "Stories of {user} were moved to **Archive**.";
"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_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?";

View File

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

View File

@ -58,6 +58,7 @@ struct SectionShow;
namespace Dialogs::Stories {
class List;
struct Content;
} // namespace Dialogs::Stories
namespace Dialogs {
@ -168,6 +169,7 @@ private:
void setupShortcuts();
void setupStories();
void storiesToggleExplicitExpand(bool expand);
void trackScroll(not_null<Ui::RpWidget*> widget);
[[nodiscard]] bool searchForPeersRequired(const QString &query) const;
[[nodiscard]] bool searchForTopicsRequired(const QString &query) const;
bool setSearchInChat(Key chat, PeerData *from = nullptr);
@ -179,6 +181,7 @@ private:
void updateControlsVisibility(bool fast = false);
void updateLockUnlockVisibility();
void updateLoadMoreChatsVisibility();
void updateStoriesVisibility();
void updateJumpToDateVisibility(bool fast = false);
void updateSearchFromVisibility(bool fast = false);
void updateControlsGeometry();
@ -268,6 +271,14 @@ private:
bool _scrollToTopIsShown = 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;
std::unique_ptr<Stories::List> _stories;
Ui::Animations::Simple _storiesExplicitExpandAnimation;
@ -276,13 +287,6 @@ private:
int _aboveScrollAdded = 0;
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;
QString _peerSearchQuery;

View File

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

View File

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

View File

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

View File

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

View File

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

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