mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-08-22 10:17:10 +00:00
Support story album links.
This commit is contained in:
parent
3c89907403
commit
985324ac12
@ -6255,6 +6255,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_view_button_emojipack" = "View emoji";
|
||||
"lng_view_button_collectible" = "View collectible";
|
||||
"lng_view_button_call" = "Join call";
|
||||
"lng_view_button_storyalbum" = "View Album";
|
||||
|
||||
"lng_sponsored_hide_ads" = "Hide";
|
||||
"lng_sponsored_title" = "What are sponsored messages?";
|
||||
@ -6466,6 +6467,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_stories_album_empty_text" = "Add some of your stories to this album.";
|
||||
"lng_stories_album_all" = "All Stories";
|
||||
"lng_stories_album_add_title" = "Add Stories";
|
||||
"lng_stories_album_share" = "Share Album";
|
||||
"lng_stories_album_edit" = "Edit Name";
|
||||
"lng_stories_album_limit_title" = "Limit Reached";
|
||||
"lng_stories_album_limit_text" = "Please remove one of the existing albums to add a new one.";
|
||||
|
@ -633,6 +633,8 @@ bool ResolveUsernameOrPhone(
|
||||
}
|
||||
const auto storyParam = params.value(u"story"_q);
|
||||
const auto storyId = storyParam.toInt();
|
||||
const auto storyAlbumParam = params.value(u"album"_q);
|
||||
const auto storyAlbumId = storyAlbumParam.toInt();
|
||||
const auto appname = webChannelPreviewLink ? QString() : appnameParam;
|
||||
const auto commentParam = params.value(u"comment"_q);
|
||||
const auto commentId = commentParam.toInt();
|
||||
@ -659,6 +661,7 @@ bool ResolveUsernameOrPhone(
|
||||
.phone = phone,
|
||||
.messageId = post,
|
||||
.storyId = storyId,
|
||||
.storyAlbumId = storyAlbumId,
|
||||
.videoTimestamp = (!videot.isEmpty()
|
||||
? ParseVideoTimestamp(videot)
|
||||
: std::optional<TimeId>()),
|
||||
@ -1827,6 +1830,7 @@ QString TryConvertUrlToLocal(QString url) {
|
||||
"/[a-zA-Z0-9\\.\\_\\-]+/?(\\?|$)|"
|
||||
"/\\d+/?(\\?|$)|"
|
||||
"/s/\\d+/?(\\?|$)|"
|
||||
"/a/\\d+/?(\\?|$)|"
|
||||
"/\\d+/\\d+/?(\\?|$)"
|
||||
")"_q, query, matchOptions)) {
|
||||
const auto domain = usernameMatch->captured(1);
|
||||
@ -1849,6 +1853,8 @@ QString TryConvertUrlToLocal(QString url) {
|
||||
added = u"&post="_q + postMatch->captured(1);
|
||||
} else if (const auto storyMatch = regex_match(u"^/s/(\\d+)(/?\\?|/?$)"_q, usernameMatch->captured(2))) {
|
||||
added = u"&story="_q + storyMatch->captured(1);
|
||||
} else if (const auto storyMatch = regex_match(u"^/a/(\\d+)(/?\\?|/?$)"_q, usernameMatch->captured(2))) {
|
||||
added = u"&album="_q + storyMatch->captured(1);
|
||||
} else if (const auto appNameMatch = regex_match(u"^/([a-zA-Z0-9\\.\\_\\-]+)(/?\\?|/?$)"_q, usernameMatch->captured(2))) {
|
||||
added = u"&appname="_q + appNameMatch->captured(1);
|
||||
}
|
||||
|
@ -1862,9 +1862,9 @@ void Stories::loadAlbums(not_null<PeerData*> peer, Albums &albums) {
|
||||
peer->input,
|
||||
MTP_long(albums.hash)
|
||||
)).done([=](const MTPstories_Albums &result) {
|
||||
auto &albums = _albums[peer->id];
|
||||
albums.requestId = 0;
|
||||
result.match([&](const MTPDstories_albums &data) {
|
||||
auto &albums = _albums[peer->id];
|
||||
albums.requestId = 0;
|
||||
albums.hash = data.vhash().v;
|
||||
auto parsed = std::vector<Data::StoryAlbum>();
|
||||
const auto &list = data.valbums().v;
|
||||
|
@ -173,6 +173,8 @@ WebPageType ParseWebPageType(
|
||||
return WebPageType::Giftcode;
|
||||
} else if (type == u"telegram_stickerset"_q) {
|
||||
return WebPageType::StickerSet;
|
||||
} else if (type == u"telegram_story_album"_q) {
|
||||
return WebPageType::StoryAlbum;
|
||||
} else if (hasIV) {
|
||||
return WebPageType::ArticleWithIV;
|
||||
} else {
|
||||
|
@ -49,6 +49,7 @@ enum class WebPageType : uint8 {
|
||||
Theme,
|
||||
Story,
|
||||
StickerSet,
|
||||
StoryAlbum,
|
||||
|
||||
Article,
|
||||
ArticleWithIV,
|
||||
|
@ -232,6 +232,8 @@ constexpr auto kSponsoredUserpicLines = 2;
|
||||
? tr::lng_view_button_emojipack(tr::now)
|
||||
: (type == WebPageType::StickerSet)
|
||||
? tr::lng_view_button_stickerset(tr::now)
|
||||
: (type == WebPageType::StoryAlbum)
|
||||
? tr::lng_view_button_storyalbum(tr::now)
|
||||
: QString());
|
||||
if (page->iv) {
|
||||
const auto manager = &page->owner().customEmojiManager();
|
||||
|
@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "info/stories/info_stories_inner_widget.h"
|
||||
|
||||
#include "apiwrap.h"
|
||||
#include "boxes/share_box.h"
|
||||
#include "data/data_peer.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_stories.h"
|
||||
@ -210,6 +211,16 @@ InnerWidget::InnerWidget(
|
||||
|
||||
_albumId.value(
|
||||
) | rpl::start_with_next([=](int albumId) {
|
||||
if (_albumsTabs
|
||||
&& (albumId == Data::kStoriesAlbumIdSaved
|
||||
|| ranges::contains(
|
||||
_albums,
|
||||
albumId,
|
||||
&Data::StoryAlbum::id))) {
|
||||
_albumsTabs->setActiveTab((albumId == Data::kStoriesAlbumIdSaved)
|
||||
? u"all"_q
|
||||
: QString::number(albumId));
|
||||
}
|
||||
_controller->replaceKey(Key(Tag(_peer, albumId, _addingToAlbumId)));
|
||||
reload();
|
||||
}, lifetime());
|
||||
@ -699,16 +710,13 @@ void InnerWidget::refreshAlbumsTabs() {
|
||||
StoryId(),
|
||||
added));
|
||||
} else {
|
||||
_albumsTabs->setActiveTab(id);
|
||||
_albumIdChanges.fire((id == u"all"_q) ? 0 : id.toInt());
|
||||
}
|
||||
}, _albumsTabs->lifetime());
|
||||
|
||||
_albumsTabs->contextMenuRequests(
|
||||
) | rpl::start_with_next([=](const QString &id) {
|
||||
if (id == u"add"_q
|
||||
|| id == u"all"_q
|
||||
|| !_peer->canEditStories()) {
|
||||
if (id == u"add"_q || id == u"all"_q) {
|
||||
return;
|
||||
}
|
||||
showMenuForAlbum(id.toInt());
|
||||
@ -723,24 +731,39 @@ void InnerWidget::refreshAlbumsTabs() {
|
||||
}
|
||||
|
||||
void InnerWidget::showMenuForAlbum(int id) {
|
||||
Expects(id > 0);
|
||||
|
||||
if (_menu || _addingToAlbumId) {
|
||||
return;
|
||||
}
|
||||
_menu = base::make_unique_q<Ui::PopupMenu>(this, st::popupMenuWithIcons);
|
||||
const auto addAction = Ui::Menu::CreateAddActionCallback(_menu);
|
||||
addAction(tr::lng_stories_album_add_title(tr::now), [=] {
|
||||
editAlbumStories(id);
|
||||
}, &st::menuIconStoriesSave);
|
||||
addAction(tr::lng_stories_album_edit(tr::now), [=] {
|
||||
editAlbumName(id);
|
||||
}, &st::menuIconEdit);
|
||||
addAction({
|
||||
.text = tr::lng_stories_album_delete(tr::now),
|
||||
.handler = [=] { confirmDeleteAlbum(id); },
|
||||
.icon = &st::menuIconDeleteAttention,
|
||||
.isAttention = true,
|
||||
});
|
||||
_menu->popup(QCursor::pos());
|
||||
if (_peer->canEditStories()) {
|
||||
addAction(tr::lng_stories_album_add_title(tr::now), [=] {
|
||||
editAlbumStories(id);
|
||||
}, &st::menuIconStoriesSave);
|
||||
}
|
||||
if (const auto username = _peer->username(); !username.isEmpty()) {
|
||||
addAction(tr::lng_stories_album_share(tr::now), [=] {
|
||||
shareAlbumLink(username, id);
|
||||
}, &st::menuIconShare);
|
||||
}
|
||||
if (_peer->canEditStories()) {
|
||||
addAction(tr::lng_stories_album_edit(tr::now), [=] {
|
||||
editAlbumName(id);
|
||||
}, &st::menuIconEdit);
|
||||
addAction({
|
||||
.text = tr::lng_stories_album_delete(tr::now),
|
||||
.handler = [=] { confirmDeleteAlbum(id); },
|
||||
.icon = &st::menuIconDeleteAttention,
|
||||
.isAttention = true,
|
||||
});
|
||||
}
|
||||
if (_menu->empty()) {
|
||||
_menu = nullptr;
|
||||
} else {
|
||||
_menu->popup(QCursor::pos());
|
||||
}
|
||||
}
|
||||
|
||||
rpl::producer<int> InnerWidget::albumIdChanges() const {
|
||||
@ -771,6 +794,12 @@ void InnerWidget::editAlbumStories(int id) {
|
||||
_controller->uiShow()->show(std::move(box));
|
||||
}
|
||||
|
||||
void InnerWidget::shareAlbumLink(const QString &username, int id) {
|
||||
const auto url = _controller->session().createInternalLinkFull(
|
||||
username + u"/a/"_q + QString::number(id));
|
||||
FastShareLink(_controller->parentController(), url);
|
||||
}
|
||||
|
||||
void InnerWidget::editAlbumName(int id) {
|
||||
const auto done = [=](QString name) {
|
||||
albumRenamed(id, name);
|
||||
|
@ -69,6 +69,7 @@ public:
|
||||
|
||||
void reload();
|
||||
void editAlbumStories(int id);
|
||||
void shareAlbumLink(const QString &username, int id);
|
||||
void editAlbumName(int id);
|
||||
void confirmDeleteAlbum(int id);
|
||||
void albumAdded(Data::StoryAlbum result);
|
||||
|
@ -18,6 +18,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "window/window_filters_menu.h"
|
||||
#include "window/window_separate_id.h"
|
||||
#include "info/channel_statistics/earn/info_channel_earn_list.h"
|
||||
#include "info/stories/info_stories_widget.h"
|
||||
#include "info/info_memento.h"
|
||||
#include "info/info_controller.h"
|
||||
#include "inline_bots/bot_attach_web_view.h"
|
||||
@ -636,6 +637,11 @@ void SessionNavigation::showPeerByLinkResolved(
|
||||
}
|
||||
} else if (info.storyId) {
|
||||
const auto storyId = FullStoryId{ peer->id, info.storyId };
|
||||
const auto context = (info.storyAlbumId > 0)
|
||||
? Data::StoriesContext{ Data::StoriesContextAlbum{
|
||||
info.storyAlbumId,
|
||||
} }
|
||||
: Data::StoriesContext{ Data::StoriesContextSingle() };
|
||||
peer->owner().stories().resolve(storyId, crl::guard(this, [=] {
|
||||
if (peer->owner().stories().lookup(storyId)) {
|
||||
parentController()->openPeerStory(
|
||||
@ -646,6 +652,8 @@ void SessionNavigation::showPeerByLinkResolved(
|
||||
showToast(tr::lng_stories_link_invalid(tr::now));
|
||||
}
|
||||
}));
|
||||
} else if (info.storyAlbumId > 0) {
|
||||
showSection(Info::Stories::Make(peer, info.storyAlbumId));
|
||||
} else if (bot && resolveType == ResolveType::BotApp) {
|
||||
const auto itemId = info.clickFromMessageId;
|
||||
const auto item = _session->data().message(itemId);
|
||||
|
@ -40,6 +40,7 @@ struct PeerByLinkInfo {
|
||||
QString chatLinkSlug;
|
||||
MsgId messageId = ShowAtUnreadMsgId;
|
||||
StoryId storyId = 0;
|
||||
int storyAlbumId = 0;
|
||||
std::optional<TimeId> videoTimestamp;
|
||||
QString text;
|
||||
RepliesByLinkInfo repliesInfo;
|
||||
|
Loading…
x
Reference in New Issue
Block a user