mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-15 21:57:10 +02:00
Load more saved / archive in the viewer.
This commit is contained in:
parent
1c41df364c
commit
881867186a
15 changed files with 301 additions and 109 deletions
|
@ -254,7 +254,10 @@ void ResolveDocument(
|
|||
&& !document->filepath().isEmpty()) {
|
||||
File::Launch(document->location(false).fname);
|
||||
} else if (controller) {
|
||||
controller->openDocument(document, msgId, topicRootId, true);
|
||||
controller->openDocument(
|
||||
document,
|
||||
true,
|
||||
{ msgId, topicRootId });
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -1109,8 +1109,7 @@ void Stories::markAsRead(FullStoryId id, bool viewed) {
|
|||
}
|
||||
}
|
||||
const auto i = _all.find(id.peer);
|
||||
Assert(i != end(_all));
|
||||
if (i->second.readTill >= id.story) {
|
||||
if (i == end(_all) || i->second.readTill >= id.story) {
|
||||
return;
|
||||
} else if (!_markReadPending.contains(id.peer)) {
|
||||
sendMarkAsReadRequests();
|
||||
|
|
|
@ -44,7 +44,7 @@ rpl::producer<StoriesIdsSlice> SavedStoriesIds(
|
|||
const auto hasBefore = int(around - begin(saved->list));
|
||||
const auto hasAfter = int(end(saved->list) - around);
|
||||
if (hasAfter < limit) {
|
||||
stories->savedLoadMore(peer->id);
|
||||
//stories->savedLoadMore(peer->id);
|
||||
}
|
||||
const auto takeBefore = std::min(hasBefore, limit);
|
||||
const auto takeAfter = std::min(hasAfter, limit);
|
||||
|
@ -116,7 +116,7 @@ rpl::producer<StoriesIdsSlice> ArchiveStoriesIds(
|
|||
const auto hasBefore = int(i - begin(archive.list));
|
||||
const auto hasAfter = int(end(archive.list) - i);
|
||||
if (hasAfter < limit) {
|
||||
stories->archiveLoadMore();
|
||||
//stories->archiveLoadMore();
|
||||
}
|
||||
const auto takeBefore = std::min(hasBefore, limit);
|
||||
const auto takeAfter = std::min(hasAfter, limit);
|
||||
|
|
|
@ -610,14 +610,14 @@ void InnerWidget::elementShowPollResults(
|
|||
void InnerWidget::elementOpenPhoto(
|
||||
not_null<PhotoData*> photo,
|
||||
FullMsgId context) {
|
||||
_controller->openPhoto(photo, context, MsgId(0));
|
||||
_controller->openPhoto(photo, { context });
|
||||
}
|
||||
|
||||
void InnerWidget::elementOpenDocument(
|
||||
not_null<DocumentData*> document,
|
||||
FullMsgId context,
|
||||
bool showInMediaView) {
|
||||
_controller->openDocument(document, context, MsgId(0), showInMediaView);
|
||||
_controller->openDocument(document, showInMediaView, { context });
|
||||
}
|
||||
|
||||
void InnerWidget::elementCancelUpload(const FullMsgId &context) {
|
||||
|
@ -1380,7 +1380,7 @@ void InnerWidget::openContextGif(FullMsgId itemId) {
|
|||
if (const auto item = session().data().message(itemId)) {
|
||||
if (const auto media = item->media()) {
|
||||
if (const auto document = media->document()) {
|
||||
_controller->openDocument(document, itemId, MsgId(), true);
|
||||
_controller->openDocument(document, true, { itemId });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2779,7 +2779,7 @@ void HistoryInner::openContextGif(FullMsgId itemId) {
|
|||
if (const auto item = session().data().message(itemId)) {
|
||||
if (const auto media = item->media()) {
|
||||
if (const auto document = media->document()) {
|
||||
_controller->openDocument(document, itemId, MsgId(), true);
|
||||
_controller->openDocument(document, true, { itemId });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3376,14 +3376,14 @@ void HistoryInner::elementShowPollResults(
|
|||
void HistoryInner::elementOpenPhoto(
|
||||
not_null<PhotoData*> photo,
|
||||
FullMsgId context) {
|
||||
_controller->openPhoto(photo, context, MsgId(0));
|
||||
_controller->openPhoto(photo, { context });
|
||||
}
|
||||
|
||||
void HistoryInner::elementOpenDocument(
|
||||
not_null<DocumentData*> document,
|
||||
FullMsgId context,
|
||||
bool showInMediaView) {
|
||||
_controller->openDocument(document, context, MsgId(0), showInMediaView);
|
||||
_controller->openDocument(document, showInMediaView, { context });
|
||||
}
|
||||
|
||||
void HistoryInner::elementCancelUpload(const FullMsgId &context) {
|
||||
|
|
|
@ -1467,9 +1467,9 @@ void HistoryWidget::applyInlineBotQuery(UserData *bot, const QString &query) {
|
|||
if (result.open) {
|
||||
const auto request = result.result->openRequest();
|
||||
if (const auto photo = request.photo()) {
|
||||
controller()->openPhoto(photo, {}, {});
|
||||
controller()->openPhoto(photo, {});
|
||||
} else if (const auto document = request.document()) {
|
||||
controller()->openDocument(document, {}, {});
|
||||
controller()->openDocument(document, false, {});
|
||||
}
|
||||
} else {
|
||||
sendInlineResult(result);
|
||||
|
|
|
@ -3059,9 +3059,9 @@ void ComposeControls::applyInlineBotQuery(
|
|||
if (result.open) {
|
||||
const auto request = result.result->openRequest();
|
||||
if (const auto photo = request.photo()) {
|
||||
_regularWindow->openPhoto(photo, {}, {});
|
||||
_regularWindow->openPhoto(photo, {});
|
||||
} else if (const auto document = request.document()) {
|
||||
_regularWindow->openDocument(document, {}, {});
|
||||
_regularWindow->openDocument(document, false, {});
|
||||
}
|
||||
} else {
|
||||
_inlineResultChosen.fire_copy(result);
|
||||
|
|
|
@ -643,14 +643,14 @@ void PinnedWidget::listShowPremiumToast(not_null<DocumentData*> document) {
|
|||
void PinnedWidget::listOpenPhoto(
|
||||
not_null<PhotoData*> photo,
|
||||
FullMsgId context) {
|
||||
controller()->openPhoto(photo, context, MsgId());
|
||||
controller()->openPhoto(photo, { context });
|
||||
}
|
||||
|
||||
void PinnedWidget::listOpenDocument(
|
||||
not_null<DocumentData*> document,
|
||||
FullMsgId context,
|
||||
bool showInMediaView) {
|
||||
controller()->openDocument(document, context, MsgId(), showInMediaView);
|
||||
controller()->openDocument(document, showInMediaView, { context });
|
||||
}
|
||||
|
||||
void PinnedWidget::listPaintEmpty(
|
||||
|
|
|
@ -2553,14 +2553,17 @@ void RepliesWidget::listShowPremiumToast(not_null<DocumentData*> document) {
|
|||
void RepliesWidget::listOpenPhoto(
|
||||
not_null<PhotoData*> photo,
|
||||
FullMsgId context) {
|
||||
controller()->openPhoto(photo, context, _rootId);
|
||||
controller()->openPhoto(photo, { context, _rootId });
|
||||
}
|
||||
|
||||
void RepliesWidget::listOpenDocument(
|
||||
not_null<DocumentData*> document,
|
||||
FullMsgId context,
|
||||
bool showInMediaView) {
|
||||
controller()->openDocument(document, context, _rootId, showInMediaView);
|
||||
controller()->openDocument(
|
||||
document,
|
||||
showInMediaView,
|
||||
{ context, _rootId });
|
||||
}
|
||||
|
||||
void RepliesWidget::listPaintEmpty(
|
||||
|
|
|
@ -1290,14 +1290,14 @@ void ScheduledWidget::listShowPremiumToast(
|
|||
void ScheduledWidget::listOpenPhoto(
|
||||
not_null<PhotoData*> photo,
|
||||
FullMsgId context) {
|
||||
controller()->openPhoto(photo, context, MsgId());
|
||||
controller()->openPhoto(photo, { context });
|
||||
}
|
||||
|
||||
void ScheduledWidget::listOpenDocument(
|
||||
not_null<DocumentData*> document,
|
||||
FullMsgId context,
|
||||
bool showInMediaView) {
|
||||
controller()->openDocument(document, context, MsgId(), showInMediaView);
|
||||
controller()->openDocument(document, showInMediaView, { context });
|
||||
}
|
||||
|
||||
void ScheduledWidget::listPaintEmpty(
|
||||
|
|
|
@ -22,6 +22,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "data/data_peer_values.h"
|
||||
#include "data/data_document.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_stories.h"
|
||||
#include "data/data_file_click_handler.h"
|
||||
#include "data/data_file_origin.h"
|
||||
#include "data/data_download_manager.h"
|
||||
|
@ -476,18 +477,31 @@ bool ListWidget::tooltipWindowActive() const {
|
|||
}
|
||||
|
||||
void ListWidget::openPhoto(not_null<PhotoData*> photo, FullMsgId id) {
|
||||
_controller->parentController()->openPhoto(photo, id, topicRootId());
|
||||
using namespace Data;
|
||||
|
||||
const auto tab = _controller->storiesTab();
|
||||
const auto context = (tab == Stories::Tab::Archive)
|
||||
? Data::StoriesContext{ Data::StoriesContextArchive() }
|
||||
: Data::StoriesContext{ Data::StoriesContextSaved() };
|
||||
_controller->parentController()->openPhoto(
|
||||
photo,
|
||||
{ id, topicRootId() },
|
||||
_controller->storiesPeer() ? &context : nullptr);
|
||||
}
|
||||
|
||||
void ListWidget::openDocument(
|
||||
not_null<DocumentData*> document,
|
||||
FullMsgId id,
|
||||
bool showInMediaView) {
|
||||
const auto tab = _controller->storiesTab();
|
||||
const auto context = (tab == Stories::Tab::Archive)
|
||||
? Data::StoriesContext{ Data::StoriesContextArchive() }
|
||||
: Data::StoriesContext{ Data::StoriesContextSaved() };
|
||||
_controller->parentController()->openDocument(
|
||||
document,
|
||||
id,
|
||||
topicRootId(),
|
||||
showInMediaView);
|
||||
showInMediaView,
|
||||
{ id, topicRootId() },
|
||||
_controller->storiesPeer() ? &context : nullptr);
|
||||
}
|
||||
|
||||
void ListWidget::trackSession(not_null<Main::Session*> session) {
|
||||
|
|
|
@ -48,6 +48,7 @@ constexpr auto kSiblingOutsidePart = 0.24;
|
|||
constexpr auto kSiblingUserpicSize = 0.3;
|
||||
constexpr auto kInnerHeightMultiplier = 1.6;
|
||||
constexpr auto kPreloadUsersCount = 3;
|
||||
constexpr auto kPreloadStoriesCount = 5;
|
||||
constexpr auto kMarkAsReadAfterSeconds = 1;
|
||||
constexpr auto kMarkAsReadAfterProgress = 0.2;
|
||||
|
||||
|
@ -432,48 +433,142 @@ auto Controller::cachedReactionIconFactory() const
|
|||
return _delegate->storiesCachedReactionIconFactory();
|
||||
}
|
||||
|
||||
void Controller::show(
|
||||
not_null<Data::Story*> story,
|
||||
Data::StoriesContext context) {
|
||||
void Controller::rebuildFromContext(
|
||||
not_null<UserData*> user,
|
||||
FullStoryId storyId) {
|
||||
using namespace Data;
|
||||
|
||||
auto &stories = story->owner().stories();
|
||||
const auto storyId = story->fullId();
|
||||
auto &stories = user->owner().stories();
|
||||
auto list = std::optional<StoriesList>();
|
||||
auto source = (const StoriesSource*)nullptr;
|
||||
const auto peerId = storyId.peer;
|
||||
const auto id = storyId.story;
|
||||
auto source = stories.source(storyId.peer);
|
||||
auto single = StoriesSource{ story->peer()->asUser() };
|
||||
v::match(context.data, [&](StoriesContextSingle) {
|
||||
source = nullptr;
|
||||
v::match(_context.data, [&](StoriesContextSingle) {
|
||||
hideSiblings();
|
||||
}, [&](StoriesContextPeer) {
|
||||
source = stories.source(peerId);
|
||||
hideSiblings();
|
||||
}, [&](StoriesContextSaved) {
|
||||
if (stories.savedCountKnown(peerId)) {
|
||||
if (const auto saved = stories.saved(peerId)) {
|
||||
const auto &ids = saved->list;
|
||||
const auto i = ids.find(id);
|
||||
if (i != end(ids)) {
|
||||
list = StoriesList{
|
||||
.user = user,
|
||||
.ids = *saved,
|
||||
.total = stories.savedCount(peerId),
|
||||
};
|
||||
_index = int(i - begin(ids));
|
||||
if (ids.size() < list->total
|
||||
&& (end(ids) - i) < kPreloadStoriesCount) {
|
||||
stories.savedLoadMore(peerId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
hideSiblings();
|
||||
}, [&](StoriesContextArchive) {
|
||||
Expects(user->isSelf());
|
||||
|
||||
if (stories.archiveCountKnown()) {
|
||||
const auto &archive = stories.archive();
|
||||
const auto &ids = archive.list;
|
||||
const auto i = ids.find(id);
|
||||
if (i != end(ids)) {
|
||||
list = StoriesList{
|
||||
.user = user,
|
||||
.ids = archive,
|
||||
.total = stories.archiveCount(),
|
||||
};
|
||||
_index = int(i - begin(ids));
|
||||
if (ids.size() < list->total
|
||||
&& (end(ids) - i) < kPreloadStoriesCount) {
|
||||
stories.archiveLoadMore();
|
||||
}
|
||||
}
|
||||
}
|
||||
hideSiblings();
|
||||
}, [&](StorySourcesList list) {
|
||||
source = stories.source(peerId);
|
||||
const auto &sources = stories.sources(list);
|
||||
const auto i = ranges::find(
|
||||
sources,
|
||||
storyId.peer,
|
||||
&StoriesSourceInfo::id);
|
||||
if (i == end(sources)) {
|
||||
source = nullptr;
|
||||
return;
|
||||
}
|
||||
showSiblings(&story->session(), sources, (i - begin(sources)));
|
||||
|
||||
if (int(sources.end() - i) < kPreloadUsersCount) {
|
||||
stories.loadMore(list);
|
||||
if (i != end(sources)) {
|
||||
showSiblings(&user->session(), sources, (i - begin(sources)));
|
||||
if (int(sources.end() - i) < kPreloadUsersCount) {
|
||||
stories.loadMore(list);
|
||||
}
|
||||
}
|
||||
});
|
||||
const auto idDates = story->idDates();
|
||||
_index = source ? (source->ids.find(idDates) - begin(source->ids)) : 0;
|
||||
if (!source || _index == source->ids.size()) {
|
||||
source = &single;
|
||||
single.ids.emplace(idDates);
|
||||
_index = 0;
|
||||
if (list) {
|
||||
_source = std::nullopt;
|
||||
if (_list != list) {
|
||||
_list = std::move(list);
|
||||
}
|
||||
} else {
|
||||
if (source) {
|
||||
const auto i = source->ids.lower_bound(StoryIdDates{ id });
|
||||
if (i != end(source->ids) && i->id == id) {
|
||||
_index = int(i - begin(source->ids));
|
||||
} else {
|
||||
source = nullptr;
|
||||
}
|
||||
}
|
||||
if (!source) {
|
||||
_source = std::nullopt;
|
||||
_list = StoriesList{
|
||||
.user = user,
|
||||
.ids = { { id } },
|
||||
.total = 1,
|
||||
};
|
||||
_index = 0;
|
||||
} else {
|
||||
_list = std::nullopt;
|
||||
if (_source != *source) {
|
||||
_source = *source;
|
||||
}
|
||||
}
|
||||
}
|
||||
_slider->show({ .index = _index, .total = shownCount() });
|
||||
}
|
||||
|
||||
void Controller::checkMoveByDelta() {
|
||||
const auto index = _index + _waitingForDelta;
|
||||
if (_waitingForDelta && shown() && index >= 0 && index < shownCount()) {
|
||||
subjumpTo(index);
|
||||
}
|
||||
}
|
||||
|
||||
void Controller::show(
|
||||
not_null<Data::Story*> story,
|
||||
Data::StoriesContext context) {
|
||||
auto &stories = story->owner().stories();
|
||||
const auto storyId = story->fullId();
|
||||
const auto user = story->peer()->asUser();
|
||||
_context = context;
|
||||
_waitingForId = {};
|
||||
_waitingForDelta = 0;
|
||||
|
||||
rebuildFromContext(user, storyId);
|
||||
_contextLifetime.destroy();
|
||||
v::match(_context.data, [&](Data::StoriesContextSaved) {
|
||||
stories.savedChanged() | rpl::filter(
|
||||
rpl::mappers::_1 == storyId.peer
|
||||
) | rpl::start_with_next([=] {
|
||||
rebuildFromContext(user, storyId);
|
||||
checkMoveByDelta();
|
||||
}, _contextLifetime);
|
||||
}, [&](Data::StoriesContextArchive) {
|
||||
stories.archiveChanged(
|
||||
) | rpl::start_with_next([=] {
|
||||
rebuildFromContext(user, storyId);
|
||||
checkMoveByDelta();
|
||||
}, _contextLifetime);
|
||||
}, [](const auto &) {});
|
||||
|
||||
const auto guard = gsl::finally([&] {
|
||||
_paused = false;
|
||||
_started = false;
|
||||
|
@ -483,11 +578,7 @@ void Controller::show(
|
|||
_photoPlayback = nullptr;
|
||||
}
|
||||
});
|
||||
if (_source != *source) {
|
||||
_source = *source;
|
||||
}
|
||||
_context = context;
|
||||
_waitingForId = {};
|
||||
|
||||
if (_shown == storyId) {
|
||||
return;
|
||||
}
|
||||
|
@ -501,13 +592,12 @@ void Controller::show(
|
|||
unfocusReply();
|
||||
}
|
||||
|
||||
_header->show({ .user = source->user, .date = story->date() });
|
||||
_slider->show({ .index = _index, .total = int(source->ids.size()) });
|
||||
_replyArea->show({ .user = source->user, .id = id });
|
||||
_header->show({ .user = user, .date = story->date() });
|
||||
_replyArea->show({ .user = user, .id = story->id() });
|
||||
_recentViews->show({
|
||||
.list = story->recentViewers(),
|
||||
.total = story->views(),
|
||||
.valid = source->user->isSelf(),
|
||||
.valid = user->isSelf(),
|
||||
});
|
||||
|
||||
const auto session = &story->session();
|
||||
|
@ -531,7 +621,7 @@ void Controller::show(
|
|||
stories.loadAround(storyId, context);
|
||||
|
||||
updatePlayingAllowed();
|
||||
source->user->updateFull();
|
||||
user->updateFull();
|
||||
}
|
||||
|
||||
void Controller::updatePlayingAllowed() {
|
||||
|
@ -634,23 +724,23 @@ void Controller::maybeMarkAsRead(const Player::TrackState &state) {
|
|||
}
|
||||
|
||||
void Controller::markAsRead() {
|
||||
Expects(_source.has_value());
|
||||
Expects(shown());
|
||||
|
||||
if (_viewed) {
|
||||
return;
|
||||
}
|
||||
_viewed = true;
|
||||
_source->user->owner().stories().markAsRead(_shown, _started);
|
||||
shownUser()->owner().stories().markAsRead(_shown, _started);
|
||||
}
|
||||
|
||||
bool Controller::subjumpAvailable(int delta) const {
|
||||
const auto index = _index + delta;
|
||||
if (index < 0) {
|
||||
return _siblingLeft && _siblingLeft->shownId().valid();
|
||||
} else if (index >= int(_source->ids.size())) {
|
||||
} else if (index >= shownCount()) {
|
||||
return _siblingRight && _siblingRight->shownId().valid();
|
||||
}
|
||||
return index >= 0 && index < int(_source->ids.size());
|
||||
return index >= 0 && index < shownCount();
|
||||
}
|
||||
|
||||
bool Controller::subjumpFor(int delta) {
|
||||
|
@ -661,12 +751,12 @@ bool Controller::subjumpFor(int delta) {
|
|||
if (index < 0) {
|
||||
if (_siblingLeft && _siblingLeft->shownId().valid()) {
|
||||
return jumpFor(-1);
|
||||
} else if (!_source || _source->ids.empty()) {
|
||||
} else if (!shown() || !shownCount()) {
|
||||
return false;
|
||||
}
|
||||
subjumpTo(0);
|
||||
return true;
|
||||
} else if (index >= int(_source->ids.size())) {
|
||||
} else if (index >= shownCount()) {
|
||||
return _siblingRight
|
||||
&& _siblingRight->shownId().valid()
|
||||
&& jumpFor(1);
|
||||
|
@ -677,27 +767,37 @@ bool Controller::subjumpFor(int delta) {
|
|||
}
|
||||
|
||||
void Controller::subjumpTo(int index) {
|
||||
Expects(_source.has_value());
|
||||
Expects(index >= 0 && index < _source->ids.size());
|
||||
Expects(shown());
|
||||
Expects(index >= 0 && index < shownCount());
|
||||
|
||||
const auto user = shownUser();
|
||||
const auto id = FullStoryId{
|
||||
.peer = _source->user->id,
|
||||
.story = (begin(_source->ids) + index)->id,
|
||||
.peer = user->id,
|
||||
.story = shownId(index),
|
||||
};
|
||||
auto &stories = _source->user->owner().stories();
|
||||
if (stories.lookup(id)) {
|
||||
_delegate->storiesJumpTo(&_source->user->session(), id, _context);
|
||||
auto &stories = user->owner().stories();
|
||||
if (!id.story) {
|
||||
const auto delta = index - _index;
|
||||
if (_waitingForDelta != delta) {
|
||||
_waitingForDelta = delta;
|
||||
_waitingForId = {};
|
||||
loadMoreToList();
|
||||
}
|
||||
} else if (stories.lookup(id)) {
|
||||
_delegate->storiesJumpTo(&user->session(), id, _context);
|
||||
} else if (_waitingForId != id) {
|
||||
_waitingForId = id;
|
||||
_waitingForDelta = 0;
|
||||
stories.loadAround(id, _context);
|
||||
}
|
||||
}
|
||||
|
||||
void Controller::checkWaitingFor() {
|
||||
Expects(_waitingForId.valid());
|
||||
Expects(_source.has_value());
|
||||
Expects(shown());
|
||||
|
||||
auto &stories = _source->user->owner().stories();
|
||||
const auto user = shownUser();
|
||||
auto &stories = user->owner().stories();
|
||||
const auto maybe = stories.lookup(_waitingForId);
|
||||
if (!maybe) {
|
||||
if (maybe.error() == Data::NoStory::Deleted) {
|
||||
|
@ -706,7 +806,7 @@ void Controller::checkWaitingFor() {
|
|||
return;
|
||||
}
|
||||
_delegate->storiesJumpTo(
|
||||
&_source->user->session(),
|
||||
&user->session(),
|
||||
base::take(_waitingForId),
|
||||
_context);
|
||||
}
|
||||
|
@ -721,7 +821,7 @@ bool Controller::jumpFor(int delta) {
|
|||
return true;
|
||||
}
|
||||
} else if (delta == 1) {
|
||||
if (_source && _index + 1 >= int(_source->ids.size())) {
|
||||
if (shown() && _index + 1 >= shownCount()) {
|
||||
markAsRead();
|
||||
}
|
||||
if (const auto right = _siblingRight.get()) {
|
||||
|
@ -817,7 +917,8 @@ Fn<void(std::vector<Data::StoryView>)> Controller::viewsGotMoreCallback() {
|
|||
return crl::guard(&_viewsLoadGuard, [=](
|
||||
const std::vector<Data::StoryView> &result) {
|
||||
if (_viewsSlice.list.empty()) {
|
||||
auto &stories = _source->user->owner().stories();
|
||||
const auto user = shownUser();
|
||||
auto &stories = user->owner().stories();
|
||||
if (const auto maybeStory = stories.lookup(_shown)) {
|
||||
_viewsSlice = {
|
||||
.list = result,
|
||||
|
@ -838,12 +939,57 @@ Fn<void(std::vector<Data::StoryView>)> Controller::viewsGotMoreCallback() {
|
|||
});
|
||||
}
|
||||
|
||||
void Controller::refreshViewsFromData() {
|
||||
Expects(_source.has_value());
|
||||
bool Controller::shown() const {
|
||||
return _source || _list;
|
||||
}
|
||||
|
||||
auto &stories = _source->user->owner().stories();
|
||||
UserData *Controller::shownUser() const {
|
||||
return _source
|
||||
? _source->user.get()
|
||||
: _list
|
||||
? _list->user.get()
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
int Controller::shownCount() const {
|
||||
return _source ? int(_source->ids.size()) : _list ? _list->total : 0;
|
||||
}
|
||||
|
||||
StoryId Controller::shownId(int index) const {
|
||||
Expects(index >= 0 && index < shownCount());
|
||||
|
||||
return _source
|
||||
? (_source->ids.begin() + index)->id
|
||||
: (index < int(_list->ids.list.size()))
|
||||
? *(_list->ids.list.begin() + index)
|
||||
: StoryId();
|
||||
}
|
||||
|
||||
void Controller::loadMoreToList() {
|
||||
Expects(shown());
|
||||
|
||||
using namespace Data;
|
||||
|
||||
const auto user = shownUser();
|
||||
const auto peerId = _shown.peer;
|
||||
auto &stories = user->owner().stories();
|
||||
v::match(_context.data, [&](StoriesContextSaved) {
|
||||
stories.savedLoadMore(peerId);
|
||||
}, [&](StoriesContextArchive) {
|
||||
Expects(user->isSelf());
|
||||
|
||||
stories.archiveLoadMore();
|
||||
}, [](const auto &) {
|
||||
});
|
||||
}
|
||||
|
||||
void Controller::refreshViewsFromData() {
|
||||
Expects(shown());
|
||||
|
||||
const auto user = shownUser();
|
||||
auto &stories = user->owner().stories();
|
||||
const auto maybeStory = stories.lookup(_shown);
|
||||
if (!maybeStory || !_source->user->isSelf()) {
|
||||
if (!maybeStory || !user->isSelf()) {
|
||||
_viewsSlice = {};
|
||||
return;
|
||||
}
|
||||
|
@ -861,11 +1007,12 @@ void Controller::refreshViewsFromData() {
|
|||
}
|
||||
|
||||
bool Controller::sliceViewsTo(PeerId offset) {
|
||||
Expects(_source.has_value());
|
||||
Expects(shown());
|
||||
|
||||
auto &stories = _source->user->owner().stories();
|
||||
const auto user = shownUser();
|
||||
auto &stories = user->owner().stories();
|
||||
const auto maybeStory = stories.lookup(_shown);
|
||||
if (!maybeStory || !_source->user->isSelf()) {
|
||||
if (!maybeStory || !user->isSelf()) {
|
||||
_viewsSlice = {};
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -135,6 +135,15 @@ public:
|
|||
[[nodiscard]] rpl::lifetime &lifetime();
|
||||
|
||||
private:
|
||||
struct StoriesList {
|
||||
not_null<UserData*> user;
|
||||
Data::StoriesIds ids;
|
||||
int total = 0;
|
||||
|
||||
friend inline bool operator==(
|
||||
const StoriesList &,
|
||||
const StoriesList &) = default;
|
||||
};
|
||||
class PhotoPlayback;
|
||||
|
||||
void initLayout();
|
||||
|
@ -166,6 +175,14 @@ private:
|
|||
[[nodiscard]] auto viewsGotMoreCallback()
|
||||
-> Fn<void(std::vector<Data::StoryView>)>;
|
||||
|
||||
[[nodiscard]] bool shown() const;
|
||||
[[nodiscard]] UserData *shownUser() const;
|
||||
[[nodiscard]] int shownCount() const;
|
||||
[[nodiscard]] StoryId shownId(int index) const;
|
||||
void rebuildFromContext(not_null<UserData*> user, FullStoryId storyId);
|
||||
void checkMoveByDelta();
|
||||
void loadMoreToList();
|
||||
|
||||
const not_null<Delegate*> _delegate;
|
||||
|
||||
rpl::variable<std::optional<Layout>> _layout;
|
||||
|
@ -194,7 +211,9 @@ private:
|
|||
TextWithEntities _captionText;
|
||||
Data::StoriesContext _context;
|
||||
std::optional<Data::StoriesSource> _source;
|
||||
std::optional<StoriesList> _list;
|
||||
FullStoryId _waitingForId;
|
||||
int _waitingForDelta = 0;
|
||||
int _index = 0;
|
||||
bool _started = false;
|
||||
bool _viewed = false;
|
||||
|
@ -211,6 +230,8 @@ private:
|
|||
Main::Session *_session = nullptr;
|
||||
rpl::lifetime _sessionLifetime;
|
||||
|
||||
rpl::lifetime _contextLifetime;
|
||||
|
||||
rpl::lifetime _lifetime;
|
||||
|
||||
};
|
||||
|
|
|
@ -2153,14 +2153,14 @@ void SessionController::hideLayer(anim::type animated) {
|
|||
|
||||
void SessionController::openPhoto(
|
||||
not_null<PhotoData*> photo,
|
||||
FullMsgId contextId,
|
||||
MsgId topicRootId) {
|
||||
const auto item = session().data().message(contextId);
|
||||
if (openSharedStory(item) || openFakeItemStory(contextId)) {
|
||||
MessageContext message,
|
||||
const Data::StoriesContext *stories) {
|
||||
const auto item = session().data().message(message.id);
|
||||
if (openSharedStory(item) || openFakeItemStory(message.id, stories)) {
|
||||
return;
|
||||
}
|
||||
_window->openInMediaView(
|
||||
Media::View::OpenRequest(this, photo, item, topicRootId));
|
||||
Media::View::OpenRequest(this, photo, item, message.topicRootId));
|
||||
}
|
||||
|
||||
void SessionController::openPhoto(
|
||||
|
@ -2171,18 +2171,21 @@ void SessionController::openPhoto(
|
|||
|
||||
void SessionController::openDocument(
|
||||
not_null<DocumentData*> document,
|
||||
FullMsgId contextId,
|
||||
MsgId topicRootId,
|
||||
bool showInMediaView) {
|
||||
const auto item = session().data().message(contextId);
|
||||
if (openSharedStory(item) || openFakeItemStory(contextId)) {
|
||||
bool showInMediaView,
|
||||
MessageContext message,
|
||||
const Data::StoriesContext *stories) {
|
||||
const auto item = session().data().message(message.id);
|
||||
if (openSharedStory(item) || openFakeItemStory(message.id, stories)) {
|
||||
return;
|
||||
} else if (showInMediaView) {
|
||||
_window->openInMediaView(
|
||||
Media::View::OpenRequest(this, document, item, topicRootId));
|
||||
_window->openInMediaView(Media::View::OpenRequest(
|
||||
this,
|
||||
document,
|
||||
item,
|
||||
message.topicRootId));
|
||||
return;
|
||||
}
|
||||
Data::ResolveDocument(this, document, item, topicRootId);
|
||||
Data::ResolveDocument(this, document, item, message.topicRootId);
|
||||
}
|
||||
|
||||
bool SessionController::openSharedStory(HistoryItem *item) {
|
||||
|
@ -2203,7 +2206,7 @@ bool SessionController::openSharedStory(HistoryItem *item) {
|
|||
|
||||
bool SessionController::openFakeItemStory(
|
||||
FullMsgId fakeItemId,
|
||||
bool forceArchiveContext) {
|
||||
const Data::StoriesContext *stories) {
|
||||
if (!peerIsUser(fakeItemId.peer)
|
||||
|| !IsStoryMsgId(fakeItemId.msg)) {
|
||||
return false;
|
||||
|
@ -2215,13 +2218,11 @@ bool SessionController::openFakeItemStory(
|
|||
if (maybeStory) {
|
||||
using namespace Data;
|
||||
const auto story = *maybeStory;
|
||||
const auto context = !story->expired()
|
||||
? StoriesContext{ StoriesContextPeer() }
|
||||
: (story->pinned() && !forceArchiveContext)
|
||||
? StoriesContext{ StoriesContextSaved() }
|
||||
: StoriesContext{ StoriesContextArchive() };
|
||||
const auto context = stories
|
||||
? *stories
|
||||
: StoriesContext{ StoriesContextSingle() };
|
||||
_window->openInMediaView(
|
||||
::Media::View::OpenRequest(this, *maybeStory, context));
|
||||
::Media::View::OpenRequest(this, story, context));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -482,20 +482,24 @@ public:
|
|||
void showPassportForm(const Passport::FormRequest &request);
|
||||
void clearPassportForm();
|
||||
|
||||
struct MessageContext {
|
||||
FullMsgId id;
|
||||
MsgId topicRootId;
|
||||
};
|
||||
void openPhoto(
|
||||
not_null<PhotoData*> photo,
|
||||
FullMsgId contextId,
|
||||
MsgId topicRootId);
|
||||
MessageContext message,
|
||||
const Data::StoriesContext *stories = nullptr);
|
||||
void openPhoto(not_null<PhotoData*> photo, not_null<PeerData*> peer);
|
||||
void openDocument(
|
||||
not_null<DocumentData*> document,
|
||||
FullMsgId contextId,
|
||||
MsgId topicRootId,
|
||||
bool showInMediaView = false);
|
||||
bool showInMediaView,
|
||||
MessageContext message,
|
||||
const Data::StoriesContext *stories = nullptr);
|
||||
bool openSharedStory(HistoryItem *item);
|
||||
bool openFakeItemStory(
|
||||
FullMsgId fakeItemId,
|
||||
bool forceArchiveContext = false);
|
||||
const Data::StoriesContext *stories = nullptr);
|
||||
|
||||
void showChooseReportMessages(
|
||||
not_null<PeerData*> peer,
|
||||
|
|
Loading…
Add table
Reference in a new issue