mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-15 21:57:10 +02:00
Support story link previews.
This commit is contained in:
parent
22b6f27f7b
commit
1b581a1597
11 changed files with 85 additions and 8 deletions
|
@ -3702,6 +3702,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
"lng_view_button_background" = "View background";
|
||||
"lng_view_button_theme" = "View theme";
|
||||
"lng_view_button_message" = "View message";
|
||||
"lng_view_button_story" = "View story";
|
||||
"lng_view_button_voice_chat" = "Voice chat";
|
||||
"lng_view_button_voice_chat_channel" = "Live stream";
|
||||
"lng_view_button_request_join" = "Request to Join";
|
||||
|
|
|
@ -779,7 +779,7 @@ QString ApiWrap::exportDirectStoryLink(not_null<Data::Story*> story) {
|
|||
const auto fallback = [&] {
|
||||
const auto base = user->username();
|
||||
const auto story = QString::number(storyId.story);
|
||||
const auto query = base + "/s" + story;
|
||||
const auto query = base + "/s/" + story;
|
||||
return session().createInternalLinkFull(query);
|
||||
};
|
||||
const auto i = _unlikelyStoryLinks.find(storyId);
|
||||
|
|
|
@ -1982,11 +1982,16 @@ MediaStory::MediaStory(not_null<HistoryItem*> parent, FullStoryId storyId)
|
|||
: Media(parent)
|
||||
, _storyId(storyId) {
|
||||
const auto stories = &parent->history()->owner().stories();
|
||||
const auto maybeStory = stories->lookup(storyId);
|
||||
if (!maybeStory) {
|
||||
if (const auto maybeStory = stories->lookup(storyId)) {
|
||||
parent->setText((*maybeStory)->caption());
|
||||
} else {
|
||||
if (maybeStory.error() == NoStory::Unknown) {
|
||||
stories->resolve(storyId, crl::guard(this, [=] {
|
||||
_expired = !stories->lookup(storyId);
|
||||
if (const auto maybeStory = stories->lookup(storyId)) {
|
||||
parent->setText((*maybeStory)->caption());
|
||||
} else {
|
||||
_expired = true;
|
||||
}
|
||||
parent->history()->owner().requestItemViewRefresh(parent);
|
||||
}));
|
||||
} else {
|
||||
|
@ -2052,6 +2057,7 @@ std::unique_ptr<HistoryView::Media> MediaStory::createView(
|
|||
const auto stories = &parent()->history()->owner().stories();
|
||||
const auto maybeStory = stories->lookup(_storyId);
|
||||
if (!maybeStory) {
|
||||
realParent->setText(TextWithEntities());
|
||||
if (maybeStory.error() == Data::NoStory::Deleted) {
|
||||
_expired = true;
|
||||
return nullptr;
|
||||
|
@ -2065,6 +2071,7 @@ std::unique_ptr<HistoryView::Media> MediaStory::createView(
|
|||
}
|
||||
_expired = false;
|
||||
const auto story = *maybeStory;
|
||||
realParent->setText(story->caption());
|
||||
if (const auto photo = story->photo()) {
|
||||
return std::make_unique<HistoryView::Photo>(
|
||||
message,
|
||||
|
|
|
@ -3215,6 +3215,7 @@ not_null<WebPageData*> Session::processWebpage(const MTPDwebPagePending &data) {
|
|||
QString(),
|
||||
QString(),
|
||||
TextWithEntities(),
|
||||
FullStoryId(),
|
||||
nullptr,
|
||||
nullptr,
|
||||
WebPageCollage(),
|
||||
|
@ -3269,6 +3270,7 @@ not_null<WebPageData*> Session::webpage(
|
|||
siteName,
|
||||
title,
|
||||
description,
|
||||
FullStoryId(),
|
||||
photo,
|
||||
document,
|
||||
std::move(collage),
|
||||
|
@ -3321,16 +3323,55 @@ void Session::webpageApplyFields(
|
|||
}
|
||||
return nullptr;
|
||||
};
|
||||
auto story = (Data::Story*)nullptr;
|
||||
auto storyId = FullStoryId();
|
||||
if (const auto attributes = data.vattributes()) {
|
||||
for (const auto &attribute : attributes->v) {
|
||||
attribute.match([&](const MTPDwebPageAttributeStory &data) {
|
||||
storyId = FullStoryId{
|
||||
peerFromUser(data.vuser_id()),
|
||||
data.vid().v,
|
||||
};
|
||||
if (const auto embed = data.vstory()) {
|
||||
story = stories().applyFromWebpage(
|
||||
peerFromUser(data.vuser_id()),
|
||||
*embed);
|
||||
} else if (const auto maybe = stories().lookup(storyId)) {
|
||||
story = *maybe;
|
||||
} else if (maybe.error() == Data::NoStory::Unknown) {
|
||||
stories().resolve(storyId, [=] {
|
||||
if (const auto maybe = stories().lookup(storyId)) {
|
||||
const auto story = *maybe;
|
||||
page->document = story->document();
|
||||
page->photo = story->photo();
|
||||
page->description = story->caption();
|
||||
page->type = WebPageType::Story;
|
||||
notifyWebPageUpdateDelayed(page);
|
||||
}
|
||||
});
|
||||
}
|
||||
}, [](const auto &) {});
|
||||
}
|
||||
}
|
||||
webpageApplyFields(
|
||||
page,
|
||||
ParseWebPageType(data),
|
||||
(story ? WebPageType::Story : ParseWebPageType(data)),
|
||||
qs(data.vurl()),
|
||||
qs(data.vdisplay_url()),
|
||||
siteName,
|
||||
qs(data.vtitle().value_or_empty()),
|
||||
description,
|
||||
photo ? processPhoto(*photo).get() : nullptr,
|
||||
document ? processDocument(*document).get() : lookupThemeDocument(),
|
||||
(story ? story->caption() : description),
|
||||
storyId,
|
||||
(story
|
||||
? story->photo()
|
||||
: photo
|
||||
? processPhoto(*photo).get()
|
||||
: nullptr),
|
||||
(story
|
||||
? story->document()
|
||||
: document
|
||||
? processDocument(*document).get()
|
||||
: lookupThemeDocument()),
|
||||
WebPageCollage(this, data),
|
||||
data.vduration().value_or_empty(),
|
||||
qs(data.vauthor().value_or_empty()),
|
||||
|
@ -3345,6 +3386,7 @@ void Session::webpageApplyFields(
|
|||
const QString &siteName,
|
||||
const QString &title,
|
||||
const TextWithEntities &description,
|
||||
FullStoryId storyId,
|
||||
PhotoData *photo,
|
||||
DocumentData *document,
|
||||
WebPageCollage &&collage,
|
||||
|
@ -3359,6 +3401,7 @@ void Session::webpageApplyFields(
|
|||
siteName,
|
||||
title,
|
||||
description,
|
||||
storyId,
|
||||
photo,
|
||||
document,
|
||||
std::move(collage),
|
||||
|
|
|
@ -811,6 +811,7 @@ private:
|
|||
const QString &siteName,
|
||||
const QString &title,
|
||||
const TextWithEntities &description,
|
||||
FullStoryId storyId,
|
||||
PhotoData *photo,
|
||||
DocumentData *document,
|
||||
WebPageCollage &&collage,
|
||||
|
|
|
@ -455,6 +455,17 @@ void Stories::apply(not_null<PeerData*> peer, const MTPUserStories *data) {
|
|||
}
|
||||
}
|
||||
|
||||
Story *Stories::applyFromWebpage(PeerId peerId, const MTPstoryItem &story) {
|
||||
const auto idDates = parseAndApply(
|
||||
_owner->peer(peerId),
|
||||
story,
|
||||
base::unixtime::now());
|
||||
const auto value = idDates
|
||||
? lookup({ peerId, idDates.id })
|
||||
: base::make_unexpected(NoStory::Deleted);
|
||||
return value ? value->get() : nullptr;
|
||||
}
|
||||
|
||||
void Stories::requestUserStories(not_null<UserData*> user) {
|
||||
if (!_requestingUserStories.emplace(user).second) {
|
||||
return;
|
||||
|
|
|
@ -244,6 +244,7 @@ public:
|
|||
void loadMore(StorySourcesList list);
|
||||
void apply(const MTPDupdateStory &data);
|
||||
void apply(not_null<PeerData*> peer, const MTPUserStories *data);
|
||||
Story *applyFromWebpage(PeerId peerId, const MTPstoryItem &story);
|
||||
void loadAround(FullStoryId id, StoriesContext context);
|
||||
|
||||
const StoriesSource *source(PeerId id) const;
|
||||
|
|
|
@ -152,6 +152,8 @@ WebPageType ParseWebPageType(
|
|||
return WebPageType::WallPaper;
|
||||
} else if (type == u"telegram_theme"_q) {
|
||||
return WebPageType::Theme;
|
||||
} else if (type == u"telegram_story"_q) {
|
||||
return WebPageType::Story;
|
||||
} else if (type == u"telegram_channel"_q) {
|
||||
return WebPageType::Channel;
|
||||
} else if (type == u"telegram_channel_request"_q) {
|
||||
|
@ -214,6 +216,7 @@ bool WebPageData::applyChanges(
|
|||
const QString &newSiteName,
|
||||
const QString &newTitle,
|
||||
const TextWithEntities &newDescription,
|
||||
FullStoryId newStoryId,
|
||||
PhotoData *newPhoto,
|
||||
DocumentData *newDocument,
|
||||
WebPageCollage &&newCollage,
|
||||
|
@ -254,6 +257,7 @@ bool WebPageData::applyChanges(
|
|||
&& siteName == resultSiteName
|
||||
&& title == resultTitle
|
||||
&& description.text == newDescription.text
|
||||
&& storyId == newStoryId
|
||||
&& photo == newPhoto
|
||||
&& document == newDocument
|
||||
&& collage.items == newCollage.items
|
||||
|
@ -271,6 +275,7 @@ bool WebPageData::applyChanges(
|
|||
siteName = resultSiteName;
|
||||
title = resultTitle;
|
||||
description = newDescription;
|
||||
storyId = newStoryId;
|
||||
photo = newPhoto;
|
||||
document = newDocument;
|
||||
collage = std::move(newCollage);
|
||||
|
|
|
@ -35,6 +35,7 @@ enum class WebPageType {
|
|||
|
||||
WallPaper,
|
||||
Theme,
|
||||
Story,
|
||||
|
||||
Article,
|
||||
ArticleWithIV,
|
||||
|
@ -70,6 +71,7 @@ struct WebPageData {
|
|||
const QString &newSiteName,
|
||||
const QString &newTitle,
|
||||
const TextWithEntities &newDescription,
|
||||
FullStoryId newStoryId,
|
||||
PhotoData *newPhoto,
|
||||
DocumentData *newDocument,
|
||||
WebPageCollage &&newCollage,
|
||||
|
@ -89,6 +91,7 @@ struct WebPageData {
|
|||
QString siteName;
|
||||
QString title;
|
||||
TextWithEntities description;
|
||||
FullStoryId storyId;
|
||||
int duration = 0;
|
||||
QString author;
|
||||
PhotoData *photo = nullptr;
|
||||
|
|
|
@ -52,6 +52,8 @@ inline auto WebPageToPhrase(not_null<WebPageData*> webpage) {
|
|||
const auto type = webpage->type;
|
||||
return Ui::Text::Upper((type == WebPageType::Theme)
|
||||
? tr::lng_view_button_theme(tr::now)
|
||||
: (type == WebPageType::Story)
|
||||
? tr::lng_view_button_story(tr::now)
|
||||
: (type == WebPageType::Message)
|
||||
? tr::lng_view_button_message(tr::now)
|
||||
: (type == WebPageType::Group)
|
||||
|
@ -139,6 +141,8 @@ bool ViewButton::MediaHasViewButton(
|
|||
|| ((type == WebPageType::Theme)
|
||||
&& webpage->document
|
||||
&& webpage->document->isTheme())
|
||||
|| ((type == WebPageType::Story)
|
||||
&& (webpage->photo || webpage->document))
|
||||
|| ((type == WebPageType::WallPaper)
|
||||
&& webpage->document
|
||||
&& webpage->document->isWallPaper());
|
||||
|
|
|
@ -168,6 +168,7 @@ QSize WebPage::countOptimalSize() {
|
|||
&& _data->photo
|
||||
&& _data->type != WebPageType::Photo
|
||||
&& _data->type != WebPageType::Document
|
||||
&& _data->type != WebPageType::Story
|
||||
&& _data->type != WebPageType::Video) {
|
||||
if (_data->type == WebPageType::Profile) {
|
||||
_asArticle = true;
|
||||
|
|
Loading…
Add table
Reference in a new issue