diff --git a/Telegram/SourceFiles/media/stories/media_stories_controller.cpp b/Telegram/SourceFiles/media/stories/media_stories_controller.cpp index bd6c19b644..2bdb190989 100644 --- a/Telegram/SourceFiles/media/stories/media_stories_controller.cpp +++ b/Telegram/SourceFiles/media/stories/media_stories_controller.cpp @@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "base/timer.h" #include "base/power_save_blocker.h" #include "base/qt_signal_producer.h" +#include "base/unixtime.h" #include "boxes/peers/prepare_short_info_box.h" #include "chat_helpers/compose/compose_show.h" #include "core/application.h" @@ -75,6 +76,42 @@ constexpr auto kPreloadPreviousMediaCount = 1; constexpr auto kMarkAsReadAfterSeconds = 0.2; constexpr auto kMarkAsReadAfterProgress = 0.; +struct SameDayRange { + int from = 0; + int till = 0; +}; +[[nodiscard]] SameDayRange ComputeSameDayRange( + not_null story, + const Data::StoriesIds &ids, + int index) { + Expects(index >= 0 && index < ids.list.size()); + + auto result = SameDayRange{ .from = index, .till = index }; + const auto peerId = story->peer()->id; + const auto stories = &story->owner().stories(); + const auto now = base::unixtime::parse(story->date()); + const auto b = begin(ids.list); + for (auto i = b + index; i != b;) { + if (const auto maybeStory = stories->lookup({ peerId, *--i })) { + const auto day = base::unixtime::parse((*maybeStory)->date()); + if (day.date() != now.date()) { + break; + } + } + --result.from; + } + for (auto i = b + index + 1, e = end(ids.list); i != e; ++i) { + if (const auto maybeStory = stories->lookup({ peerId, *i })) { + const auto day = base::unixtime::parse((*maybeStory)->date()); + if (day.date() != now.date()) { + break; + } + } + ++result.till; + } + return result; +} + } // namespace class Controller::PhotoPlayback final { @@ -629,11 +666,19 @@ void Controller::rebuildFromContext( } } }); + _sliderIndex = 0; + _sliderCount = 0; if (list) { _source = std::nullopt; if (_list != list) { _list = std::move(list); } + if (const auto maybe = user->owner().stories().lookup(storyId)) { + const auto now = *maybe; + const auto range = ComputeSameDayRange(now, _list->ids, _index); + _sliderCount = range.till - range.from + 1; + _sliderIndex = _index - range.from; + } } else { if (source) { const auto i = source->ids.lower_bound(StoryIdDates{ id }); @@ -659,7 +704,10 @@ void Controller::rebuildFromContext( } } preloadNext(); - _slider->show({ .index = _index, .total = shownCount() }); + _slider->show({ + .index = _sliderCount ? _sliderIndex : _index, + .total = _sliderCount ? _sliderCount : shownCount(), + }); } void Controller::preloadNext() { @@ -750,6 +798,8 @@ void Controller::show( _header->show({ .user = user, .date = story->date(), + .fullIndex = _sliderCount ? _index : 0, + .fullCount = _sliderCount ? shownCount() : 0, .edited = story->edited(), }); if (!changeShown(story)) { diff --git a/Telegram/SourceFiles/media/stories/media_stories_controller.h b/Telegram/SourceFiles/media/stories/media_stories_controller.h index 37d7b60fba..0df907acd6 100644 --- a/Telegram/SourceFiles/media/stories/media_stories_controller.h +++ b/Telegram/SourceFiles/media/stories/media_stories_controller.h @@ -241,6 +241,8 @@ private: FullStoryId _waitingForId; int _waitingForDelta = 0; int _index = 0; + int _sliderIndex = 0; + int _sliderCount = 0; bool _started = false; bool _viewed = false; diff --git a/Telegram/SourceFiles/media/stories/media_stories_header.cpp b/Telegram/SourceFiles/media/stories/media_stories_header.cpp index fd8f21b331..ab2a842e98 100644 --- a/Telegram/SourceFiles/media/stories/media_stories_header.cpp +++ b/Telegram/SourceFiles/media/stories/media_stories_header.cpp @@ -15,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/controls/userpic_button.h" #include "ui/layers/box_content.h" #include "ui/text/format_values.h" +#include "ui/text/text_utilities.h" #include "ui/widgets/labels.h" #include "ui/painter.h" #include "ui/rp_widget.h" @@ -75,6 +76,16 @@ struct Timestamp { return { Ui::FormatDateTime(whenFull) }; } +[[nodiscard]] TextWithEntities ComposeName(HeaderData data) { + auto result = Ui::Text::Bold(data.user->shortName()); + if (data.fullCount) { + result.append(QString::fromUtf8(" \xE2\x80\xA2 %1/%2" + ).arg(data.fullIndex + 1 + ).arg(data.fullCount)); + } + return result; +} + [[nodiscard]] Timestamp ComposeDetails(HeaderData data, TimeId now) { auto result = ComposeTimestamp(data.date, now); if (data.edited) { @@ -98,9 +109,12 @@ void Header::show(HeaderData data) { if (_data == data) { return; } - const auto userChanged = (!_data || _data->user != data.user); + const auto nameDataChanged = !_data + || (_data->user != data.user) + || (_data->fullCount != data.fullCount) + || (data.fullCount && _data->fullIndex != data.fullIndex); _data = data; - if (userChanged) { + if (nameDataChanged) { _date = nullptr; const auto parent = _controller->wrap(); auto widget = std::make_unique(parent); @@ -119,7 +133,7 @@ void Header::show(HeaderData data) { st::storiesHeaderMargin.top()); const auto name = Ui::CreateChild( raw, - data.user->firstName, + rpl::single(ComposeName(data)), st::storiesHeaderName); name->setAttribute(Qt::WA_TransparentForMouseEvents); name->setOpacity(kNameOpacity); diff --git a/Telegram/SourceFiles/media/stories/media_stories_header.h b/Telegram/SourceFiles/media/stories/media_stories_header.h index cab9434645..1393eefd5b 100644 --- a/Telegram/SourceFiles/media/stories/media_stories_header.h +++ b/Telegram/SourceFiles/media/stories/media_stories_header.h @@ -22,6 +22,8 @@ class Controller; struct HeaderData { not_null user; TimeId date = 0; + int fullIndex = 0; + int fullCount = 0; bool edited = false; friend inline auto operator<=>(HeaderData, HeaderData) = default; diff --git a/Telegram/SourceFiles/media/view/media_view.style b/Telegram/SourceFiles/media/view/media_view.style index 00db429d13..ac5d9e0624 100644 --- a/Telegram/SourceFiles/media/view/media_view.style +++ b/Telegram/SourceFiles/media/view/media_view.style @@ -426,7 +426,7 @@ storiesHeaderPhoto: UserpicButton(defaultUserpicButton) { } storiesHeaderName: FlatLabel(defaultFlatLabel) { textFg: mediaviewControlFg; - style: semiboldTextStyle; + style: defaultTextStyle; } storiesHeaderNamePosition: point(50px, 0px); storiesHeaderDate: FlatLabel(defaultFlatLabel) {