Break large stories lists by days in viewer.

This commit is contained in:
John Preston 2023-07-18 22:27:12 +04:00
parent b630e48a77
commit 961dd2a4a8
5 changed files with 73 additions and 5 deletions

View File

@ -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<Data::Story*> 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)) {

View File

@ -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;

View File

@ -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<Ui::AbstractButton>(parent);
@ -119,7 +133,7 @@ void Header::show(HeaderData data) {
st::storiesHeaderMargin.top());
const auto name = Ui::CreateChild<Ui::FlatLabel>(
raw,
data.user->firstName,
rpl::single(ComposeName(data)),
st::storiesHeaderName);
name->setAttribute(Qt::WA_TransparentForMouseEvents);
name->setOpacity(kNameOpacity);

View File

@ -22,6 +22,8 @@ class Controller;
struct HeaderData {
not_null<UserData*> user;
TimeId date = 0;
int fullIndex = 0;
int fullCount = 0;
bool edited = false;
friend inline auto operator<=>(HeaderData, HeaderData) = default;

View File

@ -426,7 +426,7 @@ storiesHeaderPhoto: UserpicButton(defaultUserpicButton) {
}
storiesHeaderName: FlatLabel(defaultFlatLabel) {
textFg: mediaviewControlFg;
style: semiboldTextStyle;
style: defaultTextStyle;
}
storiesHeaderNamePosition: point(50px, 0px);
storiesHeaderDate: FlatLabel(defaultFlatLabel) {