diff --git a/Telegram/SourceFiles/boxes/peer_list_controllers.cpp b/Telegram/SourceFiles/boxes/peer_list_controllers.cpp index 3b984c171a..e8395b98cd 100644 --- a/Telegram/SourceFiles/boxes/peer_list_controllers.cpp +++ b/Telegram/SourceFiles/boxes/peer_list_controllers.cpp @@ -132,27 +132,36 @@ QBrush PeerListStoriesGradient(const style::PeerList &st) { } std::vector PeerListStoriesSegments( - int count, - int unread, + PeerListStoriesCounts counts, const QBrush &unreadBrush) { - Expects(unread <= count); - Expects(count > 0); + Expects(counts.unread <= counts.count); + Expects(counts.count > 0); auto result = std::vector(); const auto add = [&](bool unread) { result.push_back({ - .brush = unread ? unreadBrush : st::dialogsUnreadBgMuted->b, + .brush = (counts.videoStream + ? st::attentionButtonFg->b + : unread + ? unreadBrush + : st::dialogsUnreadBgMuted->b), .width = (unread ? st::dialogsStoriesFull.lineTwice / 2. : st::dialogsStoriesFull.lineReadTwice / 2.), }); }; - result.reserve(count); - for (auto i = 0, till = count - unread; i != till; ++i) { - add(false); - } - for (auto i = 0; i != unread; ++i) { + if (counts.videoStream) { add(true); + } else { + const auto count = counts.count; + const auto unread = counts.unread; + result.reserve(count); + for (auto i = 0, till = count - unread; i != till; ++i) { + add(false); + } + for (auto i = 0; i != unread; ++i) { + add(true); + } } return result; } @@ -521,18 +530,15 @@ void PeerListStories::updateColors() { for (auto i = begin(_counts); i != end(_counts); ++i) { if (const auto row = _delegate->peerListFindRow(i->first)) { if (i->second.count >= 0 && i->second.unread >= 0) { - applyForRow(row, i->second.count, i->second.unread, true); + applyForRow(row, i->second, true); } } } } -void PeerListStories::updateFor( - uint64 id, - int count, - int unread) { +void PeerListStories::updateFor(uint64 id, Counts counts) { if (const auto row = _delegate->peerListFindRow(id)) { - applyForRow(row, count, unread); + applyForRow(row, counts); _delegate->peerListUpdateRow(row); } } @@ -550,11 +556,14 @@ void PeerListStories::process(not_null row) { ? 1 : 0; const auto unread = source - ? source->info().unreadCount + ? int(source->info().unreadCount) : user->hasUnreadStories() ? 1 : 0; - applyForRow(row, count, unread, true); + const auto videoStream = source + ? bool(source->info().hasVideoStream) + : user->hasActiveVideoStream(); + applyForRow(row, { count, unread, videoStream }, true); } bool PeerListStories::handleClick(not_null peer) { @@ -597,25 +606,27 @@ void PeerListStories::prepare(not_null delegate) { const auto info = source ? source->info() : Data::StoriesSourceInfo(); - updateFor(id.value, info.count, info.unreadCount); + updateFor(id.value, { + int(info.count), + int(info.unreadCount), + bool(info.hasVideoStream), + }); }, _lifetime); } void PeerListStories::applyForRow( not_null row, - int count, - int unread, + Counts counts, bool force) { - auto &counts = _counts[row->id()]; - if (!force && counts.count == count && counts.unread == unread) { + auto &existing = _counts[row->id()]; + if (!force && existing == counts) { return; } - counts.count = count; - counts.unread = unread; - _delegate->peerListSetRowChecked(row, count > 0); - if (count > 0) { + existing = counts; + _delegate->peerListSetRowChecked(row, counts.count > 0); + if (counts.count > 0) { row->setCustomizedCheckSegments( - PeerListStoriesSegments(count, unread, _unreadBrush)); + PeerListStoriesSegments(counts, _unreadBrush)); } } diff --git a/Telegram/SourceFiles/boxes/peer_list_controllers.h b/Telegram/SourceFiles/boxes/peer_list_controllers.h index 24887d3df2..fa02b17a58 100644 --- a/Telegram/SourceFiles/boxes/peer_list_controllers.h +++ b/Telegram/SourceFiles/boxes/peer_list_controllers.h @@ -42,9 +42,18 @@ class SessionController; [[nodiscard]] object_ptr PrepareContactsBox( not_null sessionController); [[nodiscard]] QBrush PeerListStoriesGradient(const style::PeerList &st); + +struct PeerListStoriesCounts { + int count = 0; + int unread = 0; + bool videoStream = false; + + friend inline bool operator==( + const PeerListStoriesCounts &a, + const PeerListStoriesCounts &b) = default; +}; [[nodiscard]] std::vector PeerListStoriesSegments( - int count, - int unread, + PeerListStoriesCounts counts, const QBrush &unreadBrush); class PeerListRowWithLink : public PeerListRow { @@ -211,17 +220,13 @@ public: bool handleClick(not_null peer); private: - struct Counts { - int count = 0; - int unread = 0; - }; + using Counts = PeerListStoriesCounts; void updateColors(); - void updateFor(uint64 id, int count, int unread); + void updateFor(uint64 id, Counts counts); void applyForRow( not_null row, - int count, - int unread, + Counts counts, bool force = false); const not_null _controller; diff --git a/Telegram/SourceFiles/data/data_channel.cpp b/Telegram/SourceFiles/data/data_channel.cpp index f348378de0..5306f059e2 100644 --- a/Telegram/SourceFiles/data/data_channel.cpp +++ b/Telegram/SourceFiles/data/data_channel.cpp @@ -1158,20 +1158,34 @@ bool ChannelData::hasUnreadStories() const { return flags() & Flag::HasUnreadStories; } +bool ChannelData::hasActiveVideoStream() const { + return flags() & Flag::HasActiveVideoStream; +} + void ChannelData::setStoriesState(StoriesState state) { Expects(state != StoriesState::Unknown); const auto was = flags(); switch (state) { case StoriesState::None: - _flags.remove(Flag::HasActiveStories | Flag::HasUnreadStories); + _flags.remove(Flag::HasActiveStories + | Flag::HasUnreadStories + | Flag::HasActiveVideoStream); break; case StoriesState::HasRead: - _flags.set( - (flags() & ~Flag::HasUnreadStories) | Flag::HasActiveStories); + _flags.set(Flag::HasActiveStories + | (was + & ~(Flag::HasUnreadStories | Flag::HasActiveVideoStream))); break; case StoriesState::HasUnread: - _flags.add(Flag::HasActiveStories | Flag::HasUnreadStories); + _flags.set((was & ~Flag::HasActiveVideoStream) + | Flag::HasActiveStories + | Flag::HasUnreadStories); + break; + case StoriesState::HasVideoStream: + _flags.set((was & ~Flag::HasUnreadStories) + | Flag::HasActiveStories + | Flag::HasActiveVideoStream); break; } if (flags() != was) { diff --git a/Telegram/SourceFiles/data/data_channel.h b/Telegram/SourceFiles/data/data_channel.h index e9290a5cbe..6efc41f4a7 100644 --- a/Telegram/SourceFiles/data/data_channel.h +++ b/Telegram/SourceFiles/data/data_channel.h @@ -85,6 +85,7 @@ enum class ChannelDataFlag : uint64 { ForumTabs = (1ULL << 42), HasStarsPerMessage = (1ULL << 43), StarsPerMessageKnown = (1ULL << 44), + HasActiveVideoStream = (1ULL << 45), }; inline constexpr bool is_flag_type(ChannelDataFlag) { return true; }; using ChannelDataFlags = base::flags; @@ -536,6 +537,7 @@ public: [[nodiscard]] bool hasActiveStories() const; [[nodiscard]] bool hasUnreadStories() const; + [[nodiscard]] bool hasActiveVideoStream() const; void setStoriesState(StoriesState state); [[nodiscard]] Data::Forum *forum() const { diff --git a/Telegram/SourceFiles/data/data_peer.cpp b/Telegram/SourceFiles/data/data_peer.cpp index 8aeef7eeab..aa33c7d2c6 100644 --- a/Telegram/SourceFiles/data/data_peer.cpp +++ b/Telegram/SourceFiles/data/data_peer.cpp @@ -1984,6 +1984,15 @@ bool PeerData::hasUnreadStories() const { return false; } +bool PeerData::hasActiveVideoStream() const { + if (const auto user = asUser()) { + return user->hasActiveVideoStream(); + } else if (const auto channel = asChannel()) { + return channel->hasActiveVideoStream(); + } + return false; +} + void PeerData::setStoriesState(StoriesState state) { if (const auto user = asUser()) { return user->setStoriesState(state); diff --git a/Telegram/SourceFiles/data/data_peer.h b/Telegram/SourceFiles/data/data_peer.h index ee1dec1512..6641b69ab1 100644 --- a/Telegram/SourceFiles/data/data_peer.h +++ b/Telegram/SourceFiles/data/data_peer.h @@ -575,9 +575,11 @@ public: None, HasRead, HasUnread, + HasVideoStream, }; [[nodiscard]] bool hasActiveStories() const; [[nodiscard]] bool hasUnreadStories() const; + [[nodiscard]] bool hasActiveVideoStream() const; void setStoriesState(StoriesState state); [[nodiscard]] int peerGiftsCount() const; diff --git a/Telegram/SourceFiles/data/data_session.cpp b/Telegram/SourceFiles/data/data_session.cpp index 04946f1533..dbced5f1fc 100644 --- a/Telegram/SourceFiles/data/data_session.cpp +++ b/Telegram/SourceFiles/data/data_session.cpp @@ -594,7 +594,7 @@ not_null Session::processUser(const MTPUser &data) { ? Data::Stories::PeerSourceState() : !data.vstories_max_id() ? std::optional() - : stories().peerSourceState(result, data.vstories_max_id()->v); + : stories().peerSourceState(result, *data.vstories_max_id()); const auto flagsSet = (data.is_deleted() ? Flag::Deleted : Flag()) | (data.is_verified() ? Flag::Verified : Flag()) | (data.is_scam() ? Flag::Scam : Flag()) @@ -646,11 +646,13 @@ not_null Session::processUser(const MTPUser &data) { } } else { if (storiesState) { - result->setStoriesState(!storiesState->maxId - ? UserData::StoriesState::None + result->setStoriesState(storiesState->hasVideoStream + ? PeerData::StoriesState::HasVideoStream + : !storiesState->maxId + ? PeerData::StoriesState::None : (storiesState->maxId > storiesState->readTill) - ? UserData::StoriesState::HasUnread - : UserData::StoriesState::HasRead); + ? PeerData::StoriesState::HasUnread + : PeerData::StoriesState::HasRead); } if (data.is_self()) { result->input = MTP_inputPeerSelf(); @@ -1034,7 +1036,7 @@ not_null Session::processChat(const MTPChat &data) { ? Data::Stories::PeerSourceState() : !data.vstories_max_id() ? std::optional() - : stories().peerSourceState(channel, data.vstories_max_id()->v); + : stories().peerSourceState(channel, *data.vstories_max_id()); const auto flagsSet = (data.is_broadcast() ? Flag::Broadcast : Flag()) | (data.is_verified() ? Flag::Verified : Flag()) | (data.is_scam() ? Flag::Scam : Flag()) @@ -1080,11 +1082,13 @@ not_null Session::processChat(const MTPChat &data) { channel->setBotVerifyDetailsIcon( data.vbot_verification_icon().value_or_empty()); if (!minimal && storiesState) { - result->setStoriesState(!storiesState->maxId - ? UserData::StoriesState::None + result->setStoriesState(storiesState->hasVideoStream + ? PeerData::StoriesState::HasVideoStream + : !storiesState->maxId + ? PeerData::StoriesState::None : (storiesState->maxId > storiesState->readTill) - ? UserData::StoriesState::HasUnread - : UserData::StoriesState::HasRead); + ? PeerData::StoriesState::HasUnread + : PeerData::StoriesState::HasRead); } channel->setPhoto(data.vphoto()); @@ -5043,7 +5047,7 @@ void Session::serviceNotification( MTPstring(), // lang_code MTPEmojiStatus(), MTPVector(), - MTPint(), // stories_max_id + MTPRecentStory(), MTPPeerColor(), // color MTPPeerColor(), // profile_color MTPint(), // bot_active_users diff --git a/Telegram/SourceFiles/data/data_stories.cpp b/Telegram/SourceFiles/data/data_stories.cpp index 743765cfcf..2079b7423d 100644 --- a/Telegram/SourceFiles/data/data_stories.cpp +++ b/Telegram/SourceFiles/data/data_stories.cpp @@ -2286,18 +2286,25 @@ void Stories::setPreloadingInViewer(std::vector ids) { std::optional Stories::peerSourceState( not_null peer, - StoryId storyMaxId) { + const MTPRecentStory &recent) { + const auto &data = recent.data(); + const auto maxId = data.vmax_id().value_or_empty(); + const auto live = data.is_is_live(); const auto i = _readTill.find(peer->id); if (_readTillReceived || (i != end(_readTill))) { return PeerSourceState{ - .maxId = storyMaxId, + .maxId = maxId, .readTill = std::min( - storyMaxId, + maxId, (i != end(_readTill)) ? i->second : 0), + .hasVideoStream = live, }; } requestReadTills(); - _pendingPeerStateMaxId[peer] = storyMaxId; + _pendingPeerRecentState[peer] = RecentState{ + .maxId = maxId, + .hasVideoStream = live, + }; return std::nullopt; } @@ -2310,8 +2317,8 @@ void Stories::requestReadTills() { )).done([=](const MTPUpdates &result) { _readTillReceived = true; api->applyUpdates(result); - for (auto &[peer, maxId] : base::take(_pendingPeerStateMaxId)) { - updatePeerStoriesState(peer); + for (auto &[peer, recent] : base::take(_pendingPeerRecentState)) { + updatePeerStoriesState(peer, recent); } for (const auto &storyId : base::take(_pendingReadTillItems)) { _owner->refreshStoryItemViews(storyId); @@ -2435,20 +2442,32 @@ void Stories::sendPollingViewsRequests() { _pollingViewsTimer.callOnce(kPollViewsInterval); } -void Stories::updatePeerStoriesState(not_null peer) { +void Stories::updatePeerStoriesState( + not_null peer, + std::optional cachedRecentState) { const auto till = _readTill.find(peer->id); const auto readTill = (till != end(_readTill)) ? till->second : 0; - const auto pendingMaxId = [&] { - const auto j = _pendingPeerStateMaxId.find(peer); - return (j != end(_pendingPeerStateMaxId)) ? j->second : 0; + const auto pendingRecentState = [&] { + if (cachedRecentState) { + return *cachedRecentState; + } + const auto j = _pendingPeerRecentState.find(peer); + return (j != end(_pendingPeerRecentState)) + ? j->second + : RecentState(); }; const auto i = _all.find(peer->id); - const auto max = (i != end(_all)) - ? (i->second.ids.empty() ? 0 : i->second.ids.back().id) - : pendingMaxId(); - peer->setStoriesState(!max + const auto recent = (i != end(_all)) + ? RecentState{ + (i->second.ids.empty() ? 0 : i->second.ids.back().id), + (!i->second.ids.empty() && i->second.ids.back().videoStream), + } + : pendingRecentState(); + peer->setStoriesState(recent.hasVideoStream + ? PeerData::StoriesState::HasVideoStream + : !recent.maxId ? PeerData::StoriesState::None - : (max <= readTill) + : (recent.maxId <= readTill) ? PeerData::StoriesState::HasRead : PeerData::StoriesState::HasUnread); } diff --git a/Telegram/SourceFiles/data/data_stories.h b/Telegram/SourceFiles/data/data_stories.h index 8bea56a10b..b7ffd9fe13 100644 --- a/Telegram/SourceFiles/data/data_stories.h +++ b/Telegram/SourceFiles/data/data_stories.h @@ -264,10 +264,11 @@ public: struct PeerSourceState { StoryId maxId = 0; StoryId readTill = 0; + bool hasVideoStream = false; }; [[nodiscard]] std::optional peerSourceState( not_null peer, - StoryId storyMaxId); + const MTPRecentStory &recent); [[nodiscard]] bool isUnread(not_null story); enum class Polling { @@ -308,7 +309,10 @@ private: uint64 hash = 0; mtpRequestId requestId = 0; }; - + struct RecentState { + StoryId maxId = 0; + bool hasVideoStream = false; + }; struct PollingSettings { int chat = 0; int viewer = 0; @@ -333,7 +337,9 @@ private: const QVector &list); void sendResolveRequests(); void finalizeResolve(FullStoryId id); - void updatePeerStoriesState(not_null peer); + void updatePeerStoriesState( + not_null peer, + std::optional cachedRecentState = std::nullopt); [[nodiscard]] Set *lookupArchive(not_null peer); void clearArchive(not_null peer); @@ -462,7 +468,7 @@ private: base::flat_map _readTill; base::flat_set _pendingReadTillItems; - base::flat_map, StoryId> _pendingPeerStateMaxId; + base::flat_map, RecentState> _pendingPeerRecentState; mtpRequestId _readTillsRequestId = 0; bool _readTillReceived = false; diff --git a/Telegram/SourceFiles/data/data_story.cpp b/Telegram/SourceFiles/data/data_story.cpp index c90b2418a2..7b7d7f19f4 100644 --- a/Telegram/SourceFiles/data/data_story.cpp +++ b/Telegram/SourceFiles/data/data_story.cpp @@ -279,7 +279,12 @@ bool Story::mine() const { } StoryIdDates Story::idDates() const { - return { _id, _date, _expires }; + return { + _id, + _date, + _expires, + std::holds_alternative>(_media.data), + }; } FullStoryId Story::fullId() const { diff --git a/Telegram/SourceFiles/data/data_story.h b/Telegram/SourceFiles/data/data_story.h index 7836838882..4d6fb17dad 100644 --- a/Telegram/SourceFiles/data/data_story.h +++ b/Telegram/SourceFiles/data/data_story.h @@ -39,6 +39,7 @@ struct StoryIdDates { StoryId id = 0; TimeId date = 0; TimeId expires = 0; + bool videoStream = false; [[nodiscard]] bool valid() const { return id != 0; diff --git a/Telegram/SourceFiles/data/data_user.cpp b/Telegram/SourceFiles/data/data_user.cpp index 8ff011a5cf..a089f21f2b 100644 --- a/Telegram/SourceFiles/data/data_user.cpp +++ b/Telegram/SourceFiles/data/data_user.cpp @@ -235,20 +235,34 @@ bool UserData::hasUnreadStories() const { return flags() & Flag::HasUnreadStories; } +bool UserData::hasActiveVideoStream() const { + return flags() & Flag::HasActiveVideoStream; +} + void UserData::setStoriesState(StoriesState state) { Expects(state != StoriesState::Unknown); const auto was = flags(); switch (state) { case StoriesState::None: - _flags.remove(Flag::HasActiveStories | Flag::HasUnreadStories); + _flags.remove(Flag::HasActiveStories + | Flag::HasUnreadStories + | Flag::HasActiveVideoStream); break; case StoriesState::HasRead: - _flags.set( - (flags() & ~Flag::HasUnreadStories) | Flag::HasActiveStories); + _flags.set(Flag::HasActiveStories + | (was + & ~(Flag::HasUnreadStories | Flag::HasActiveVideoStream))); break; case StoriesState::HasUnread: - _flags.add(Flag::HasActiveStories | Flag::HasUnreadStories); + _flags.set((was & ~Flag::HasActiveVideoStream) + | Flag::HasActiveStories + | Flag::HasUnreadStories); + break; + case StoriesState::HasVideoStream: + _flags.set((was & ~Flag::HasUnreadStories) + | Flag::HasActiveStories + | Flag::HasActiveVideoStream); break; } if (flags() != was) { diff --git a/Telegram/SourceFiles/data/data_user.h b/Telegram/SourceFiles/data/data_user.h index d798fe1fdd..2ff22ab67b 100644 --- a/Telegram/SourceFiles/data/data_user.h +++ b/Telegram/SourceFiles/data/data_user.h @@ -132,7 +132,8 @@ enum class UserDataFlag : uint32 { MessageMoneyRestrictionsKnown = (1 << 24), ReadDatesPrivate = (1 << 25), StoriesCorrespondent = (1 << 26), - Forum = (1ULL << 27), + Forum = (1 << 27), + HasActiveVideoStream = (1 << 28), }; inline constexpr bool is_flag_type(UserDataFlag) { return true; }; using UserDataFlags = base::flags; @@ -273,6 +274,7 @@ public: [[nodiscard]] bool hasActiveStories() const; [[nodiscard]] bool hasUnreadStories() const; + [[nodiscard]] bool hasActiveVideoStream() const; void setStoriesState(StoriesState state); [[nodiscard]] const Data::BusinessDetails &businessDetails() const; diff --git a/Telegram/SourceFiles/dialogs/dialogs_row.cpp b/Telegram/SourceFiles/dialogs/dialogs_row.cpp index a89903018f..9f72931b6d 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_row.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_row.cpp @@ -447,17 +447,6 @@ void Row::PaintCornerBadgeFrame( q.restore(); const auto outline = QRectF(0, 0, photoSize, photoSize); - const auto storiesUnreadCount = data->storiesUnreadCount; - const auto storiesUnreadBrush = [&] { - if (context.active || !storiesUnreadCount) { - return st::dialogsUnreadBgMutedActive->b; - } - auto gradient = Ui::UnreadStoryOutlineGradient(outline); - return QBrush(gradient); - }(); - const auto storiesBrush = context.active - ? st::dialogsUnreadBgMutedActive->b - : st::dialogsUnreadBgMuted->b; const auto storiesUnread = st::dialogsStoriesFull.lineTwice / 2.; const auto storiesLine = st::dialogsStoriesFull.lineReadTwice / 2.; auto segments = std::vector(); @@ -465,6 +454,17 @@ void Row::PaintCornerBadgeFrame( const auto storiesVideoStreamBrush = st::attentionButtonFg->b; segments.push_back({ storiesVideoStreamBrush, storiesUnread }); } else { + const auto storiesUnreadCount = data->storiesUnreadCount; + const auto storiesUnreadBrush = [&] { + if (context.active || !storiesUnreadCount) { + return st::dialogsUnreadBgMutedActive->b; + } + auto gradient = Ui::UnreadStoryOutlineGradient(outline); + return QBrush(gradient); + }(); + const auto storiesBrush = context.active + ? st::dialogsUnreadBgMutedActive->b + : st::dialogsUnreadBgMuted->b; segments.reserve(storiesCount); const auto storiesReadCount = storiesCount - storiesUnreadCount; for (auto i = 0; i != storiesReadCount; ++i) { @@ -567,7 +567,7 @@ void Row::paintUserpic( const auto storiesHas = storiesPeer ? storiesPeer->hasActiveStories() : storiesFolder - ? storiesFolder->storiesCount() + ? (storiesFolder->storiesCount() > 0) : false; if (!cornerBadgeShown && !storiesHas) { BasicRow::paintUserpic(p, entry, peer, videoUserpic, context, false); @@ -604,6 +604,8 @@ void Row::paintUserpic( : 0; const auto storiesHasVideoStream = storiesSource ? storiesSource->hasVideoStream + : (storiesPeer && storiesPeer->hasActiveVideoStream()) + ? 1 : 0; const auto limit = Ui::kOutlineSegmentsMax; const auto storiesCount = std::min(storiesCountReal, limit); diff --git a/Telegram/SourceFiles/history/view/history_view_fake_items.cpp b/Telegram/SourceFiles/history/view/history_view_fake_items.cpp index 49a310aa24..5c41eee59e 100644 --- a/Telegram/SourceFiles/history/view/history_view_fake_items.cpp +++ b/Telegram/SourceFiles/history/view/history_view_fake_items.cpp @@ -57,7 +57,7 @@ PeerId GenerateUser(not_null history, const QString &name) { MTPstring(), // lang code MTPEmojiStatus(), MTPVector(), - MTPint(), // stories_max_id + MTPRecentStory(), MTPPeerColor(), // color MTPPeerColor(), // profile_color MTPint(), // bot_active_users diff --git a/Telegram/SourceFiles/main/main_account.cpp b/Telegram/SourceFiles/main/main_account.cpp index 5a2f894ed6..c8d65d9a7c 100644 --- a/Telegram/SourceFiles/main/main_account.cpp +++ b/Telegram/SourceFiles/main/main_account.cpp @@ -170,7 +170,7 @@ void Account::createSession( MTPstring(), // lang_code MTPEmojiStatus(), MTPVector(), - MTPint(), // stories_max_id + MTPRecentStory(), MTPPeerColor(), // color MTPPeerColor(), // profile_color MTPint(), // bot_active_users diff --git a/Telegram/SourceFiles/mtproto/scheme/api.tl b/Telegram/SourceFiles/mtproto/scheme/api.tl index dcad298d90..001d7cb75b 100644 --- a/Telegram/SourceFiles/mtproto/scheme/api.tl +++ b/Telegram/SourceFiles/mtproto/scheme/api.tl @@ -85,7 +85,7 @@ storage.fileMp4#b3cea0e4 = storage.FileType; storage.fileWebp#1081464c = storage.FileType; userEmpty#d3bc4b7a id:long = User; -user#20b1422 flags:# self:flags.10?true contact:flags.11?true mutual_contact:flags.12?true deleted:flags.13?true bot:flags.14?true bot_chat_history:flags.15?true bot_nochats:flags.16?true verified:flags.17?true restricted:flags.18?true min:flags.20?true bot_inline_geo:flags.21?true support:flags.23?true scam:flags.24?true apply_min_photo:flags.25?true fake:flags.26?true bot_attach_menu:flags.27?true premium:flags.28?true attach_menu_enabled:flags.29?true flags2:# bot_can_edit:flags2.1?true close_friend:flags2.2?true stories_hidden:flags2.3?true stories_unavailable:flags2.4?true contact_require_premium:flags2.10?true bot_business:flags2.11?true bot_has_main_app:flags2.13?true bot_forum_view:flags2.16?true id:long access_hash:flags.0?long first_name:flags.1?string last_name:flags.2?string username:flags.3?string phone:flags.4?string photo:flags.5?UserProfilePhoto status:flags.6?UserStatus bot_info_version:flags.14?int restriction_reason:flags.18?Vector bot_inline_placeholder:flags.19?string lang_code:flags.22?string emoji_status:flags.30?EmojiStatus usernames:flags2.0?Vector stories_max_id:flags2.5?int color:flags2.8?PeerColor profile_color:flags2.9?PeerColor bot_active_users:flags2.12?int bot_verification_icon:flags2.14?long send_paid_messages_stars:flags2.15?long = User; +user#31774388 flags:# self:flags.10?true contact:flags.11?true mutual_contact:flags.12?true deleted:flags.13?true bot:flags.14?true bot_chat_history:flags.15?true bot_nochats:flags.16?true verified:flags.17?true restricted:flags.18?true min:flags.20?true bot_inline_geo:flags.21?true support:flags.23?true scam:flags.24?true apply_min_photo:flags.25?true fake:flags.26?true bot_attach_menu:flags.27?true premium:flags.28?true attach_menu_enabled:flags.29?true flags2:# bot_can_edit:flags2.1?true close_friend:flags2.2?true stories_hidden:flags2.3?true stories_unavailable:flags2.4?true contact_require_premium:flags2.10?true bot_business:flags2.11?true bot_has_main_app:flags2.13?true bot_forum_view:flags2.16?true id:long access_hash:flags.0?long first_name:flags.1?string last_name:flags.2?string username:flags.3?string phone:flags.4?string photo:flags.5?UserProfilePhoto status:flags.6?UserStatus bot_info_version:flags.14?int restriction_reason:flags.18?Vector bot_inline_placeholder:flags.19?string lang_code:flags.22?string emoji_status:flags.30?EmojiStatus usernames:flags2.0?Vector stories_max_id:flags2.5?RecentStory color:flags2.8?PeerColor profile_color:flags2.9?PeerColor bot_active_users:flags2.12?int bot_verification_icon:flags2.14?long send_paid_messages_stars:flags2.15?long = User; userProfilePhotoEmpty#4f11bae1 = UserProfilePhoto; userProfilePhoto#82d1f706 flags:# has_video:flags.0?true personal:flags.2?true photo_id:long stripped_thumb:flags.1?bytes dc_id:int = UserProfilePhoto; @@ -100,7 +100,7 @@ userStatusLastMonth#65899777 flags:# by_me:flags.0?true = UserStatus; chatEmpty#29562865 id:long = Chat; chat#41cbf256 flags:# creator:flags.0?true left:flags.2?true deactivated:flags.5?true call_active:flags.23?true call_not_empty:flags.24?true noforwards:flags.25?true id:long title:string photo:ChatPhoto participants_count:int date:int version:int migrated_to:flags.6?InputChannel admin_rights:flags.14?ChatAdminRights default_banned_rights:flags.18?ChatBannedRights = Chat; chatForbidden#6592a1a7 id:long title:string = Chat; -channel#fe685355 flags:# creator:flags.0?true left:flags.2?true broadcast:flags.5?true verified:flags.7?true megagroup:flags.8?true restricted:flags.9?true signatures:flags.11?true min:flags.12?true scam:flags.19?true has_link:flags.20?true has_geo:flags.21?true slowmode_enabled:flags.22?true call_active:flags.23?true call_not_empty:flags.24?true fake:flags.25?true gigagroup:flags.26?true noforwards:flags.27?true join_to_send:flags.28?true join_request:flags.29?true forum:flags.30?true flags2:# stories_hidden:flags2.1?true stories_hidden_min:flags2.2?true stories_unavailable:flags2.3?true signature_profiles:flags2.12?true autotranslation:flags2.15?true broadcast_messages_allowed:flags2.16?true monoforum:flags2.17?true forum_tabs:flags2.19?true id:long access_hash:flags.13?long title:string username:flags.6?string photo:ChatPhoto date:int restriction_reason:flags.9?Vector admin_rights:flags.14?ChatAdminRights banned_rights:flags.15?ChatBannedRights default_banned_rights:flags.18?ChatBannedRights participants_count:flags.17?int usernames:flags2.0?Vector stories_max_id:flags2.4?int color:flags2.7?PeerColor profile_color:flags2.8?PeerColor emoji_status:flags2.9?EmojiStatus level:flags2.10?int subscription_until_date:flags2.11?int bot_verification_icon:flags2.13?long send_paid_messages_stars:flags2.14?long linked_monoforum_id:flags2.18?long = Chat; +channel#1c32b11c flags:# creator:flags.0?true left:flags.2?true broadcast:flags.5?true verified:flags.7?true megagroup:flags.8?true restricted:flags.9?true signatures:flags.11?true min:flags.12?true scam:flags.19?true has_link:flags.20?true has_geo:flags.21?true slowmode_enabled:flags.22?true call_active:flags.23?true call_not_empty:flags.24?true fake:flags.25?true gigagroup:flags.26?true noforwards:flags.27?true join_to_send:flags.28?true join_request:flags.29?true forum:flags.30?true flags2:# stories_hidden:flags2.1?true stories_hidden_min:flags2.2?true stories_unavailable:flags2.3?true signature_profiles:flags2.12?true autotranslation:flags2.15?true broadcast_messages_allowed:flags2.16?true monoforum:flags2.17?true forum_tabs:flags2.19?true id:long access_hash:flags.13?long title:string username:flags.6?string photo:ChatPhoto date:int restriction_reason:flags.9?Vector admin_rights:flags.14?ChatAdminRights banned_rights:flags.15?ChatBannedRights default_banned_rights:flags.18?ChatBannedRights participants_count:flags.17?int usernames:flags2.0?Vector stories_max_id:flags2.4?RecentStory color:flags2.7?PeerColor profile_color:flags2.8?PeerColor emoji_status:flags2.9?EmojiStatus level:flags2.10?int subscription_until_date:flags2.11?int bot_verification_icon:flags2.13?long send_paid_messages_stars:flags2.14?long linked_monoforum_id:flags2.18?long = Chat; channelForbidden#17d493d5 flags:# broadcast:flags.5?true megagroup:flags.8?true id:long access_hash:long title:string until_date:flags.16?int = Chat; chatFull#2633421b flags:# can_set_username:flags.7?true has_scheduled:flags.8?true translations_disabled:flags.19?true id:long about:string participants:ChatParticipants chat_photo:flags.2?Photo notify_settings:PeerNotifySettings exported_invite:flags.13?ExportedChatInvite bot_info:flags.3?Vector pinned_msg_id:flags.6?int folder_id:flags.11?int call:flags.12?InputGroupCall ttl_period:flags.14?int groupcall_default_join_as:flags.15?Peer theme_emoticon:flags.16?string requests_pending:flags.17?int recent_requesters:flags.17?Vector available_reactions:flags.18?ChatReactions reactions_limit:flags.20?int = ChatFull; @@ -2055,6 +2055,8 @@ groupCallDonor#ee430c85 flags:# top:flags.0?true my:flags.1?true anonymous:flags phone.groupCallStars#9d1dbd26 total_stars:long top_donors:Vector chats:Vector users:Vector = phone.GroupCallStars; +recentStory#711d692d flags:# is_live:flags.0?true max_id:flags.1?int = RecentStory; + ---functions--- invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X; @@ -2786,7 +2788,7 @@ stories.activateStealthMode#57bbd166 flags:# past:flags.0?true future:flags.1?tr stories.sendReaction#7fd736b2 flags:# add_to_recent:flags.0?true peer:InputPeer story_id:int reaction:Reaction = Updates; stories.getPeerStories#2c4ada50 peer:InputPeer = stories.PeerStories; stories.getAllReadPeerStories#9b5ae7f9 = Updates; -stories.getPeerMaxIDs#535983c3 id:Vector = Vector; +stories.getPeerMaxIDs#78499170 id:Vector = Vector; stories.getChatsToSend#a56a8b60 = messages.Chats; stories.togglePeerStoriesHidden#bd0415c4 peer:InputPeer hidden:Bool = Bool; stories.getStoryReactionsList#b9b2881f flags:# forwards_first:flags.2?true peer:InputPeer id:int reaction:flags.0?Reaction offset:flags.1?string limit:int = stories.StoryReactionsList;