diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index f1089b24c1..53ac624a08 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -2220,6 +2220,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_action_message_price_paid#other" = "Messages now cost {count} Stars each in this group."; "lng_you_paid_stars#one" = "You paid {count} Star."; "lng_you_paid_stars#other" = "You paid {count} Stars."; +"lng_action_confcall_invitation" = "Call invitation..."; +"lng_action_confcall_missed" = "Missed conference call"; +"lng_action_confcall_ongoing" = "Ongoing conference call"; +"lng_action_confcall_finished" = "Conference call"; "lng_you_joined_group" = "You joined this group"; @@ -4904,6 +4908,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_group_call_rtmp_viewers#one" = "{count} viewer"; "lng_group_call_rtmp_viewers#other" = "{count} viewers"; +"lng_confcall_join_title" = "Group Call"; +"lng_confcall_join_text" = "You are invited to join a Telegram Call."; +"lng_confcall_join_button" = "Join Group Call"; + "lng_no_mic_permission" = "Telegram needs microphone access so that you can make calls and record voice messages."; "lng_player_message_today" = "today at {time}"; diff --git a/Telegram/SourceFiles/calls/calls_instance.cpp b/Telegram/SourceFiles/calls/calls_instance.cpp index 02c5fb1444..65dc10fb39 100644 --- a/Telegram/SourceFiles/calls/calls_instance.cpp +++ b/Telegram/SourceFiles/calls/calls_instance.cpp @@ -632,6 +632,8 @@ void Instance::handleGroupCallUpdate( }, [](const MTPDupdateGroupCallParticipants &data) { return data.vcall().match([&](const MTPDinputGroupCall &data) { return data.vid().v; + }, [](const MTPDinputGroupCallSlug &) -> CallId { + Unexpected("slug in Instance::handleGroupCallUpdate"); }); }, [](const auto &) -> CallId { Unexpected("Type in Instance::handleGroupCallUpdate."); diff --git a/Telegram/SourceFiles/calls/group/calls_group_call.cpp b/Telegram/SourceFiles/calls/group/calls_group_call.cpp index 8c1dbb4fee..ab1b80117c 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_call.cpp +++ b/Telegram/SourceFiles/calls/group/calls_group_call.cpp @@ -1091,6 +1091,8 @@ void GroupCall::join(const MTPInputGroupCall &inputCall) { inputCall.match([&](const MTPDinputGroupCall &data) { _id = data.vid().v; _accessHash = data.vaccess_hash().v; + }, [&](const MTPDinputGroupCallSlug &) { + Unexpected("inputGroupCallSlug in GroupCall::join."); }); setState(_scheduleDate ? State::Waiting : State::Joining); @@ -1377,7 +1379,8 @@ void GroupCall::rejoin(not_null as) { inputCall(), joinAs()->input, MTP_string(_joinHash), - MTPlong(), // key_fingerprint + MTPint256(), // public_key + MTPint(), // invite_msg_id MTP_dataJSON(MTP_bytes(json)) )).done([=]( const MTPUpdates &updates, @@ -1607,7 +1610,8 @@ void GroupCall::applyMeInCallLocally() { MTPstring(), // Don't update about text in local updates. MTP_long(raisedHandRating), MTPGroupCallParticipantVideo(), - MTPGroupCallParticipantVideo())), + MTPGroupCallParticipantVideo(), + AssertIsDebug() MTPint256())), // public_key MTP_int(0)).c_updateGroupCallParticipants()); } @@ -1654,7 +1658,8 @@ void GroupCall::applyParticipantLocally( MTPstring(), // Don't update about text in local updates. MTP_long(participant->raisedHandRating), MTPGroupCallParticipantVideo(), - MTPGroupCallParticipantVideo())), + MTPGroupCallParticipantVideo(), + AssertIsDebug() MTPint256())), // public_key MTP_int(0)).c_updateGroupCallParticipants()); } @@ -1966,8 +1971,11 @@ void GroupCall::handleUpdate(const MTPDupdateGroupCall &data) { } void GroupCall::handleUpdate(const MTPDupdateGroupCallParticipants &data) { - const auto callId = data.vcall().match([](const auto &data) { + const auto callId = data.vcall().match([]( + const MTPDinputGroupCall &data) { return data.vid().v; + }, [](const MTPDinputGroupCallSlug &) -> CallId { + Unexpected("inputGroupCallSlug in GroupCall::handleUpdate."); }); if (_id != callId) { return; diff --git a/Telegram/SourceFiles/calls/group/calls_group_common.cpp b/Telegram/SourceFiles/calls/group/calls_group_common.cpp index 487629893f..75e6de992f 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_common.cpp +++ b/Telegram/SourceFiles/calls/group/calls_group_common.cpp @@ -50,4 +50,23 @@ object_ptr ScreenSharingPrivacyRequestBox() { #endif // Q_OS_MAC } +void ConferenceCallJoinConfirm( + not_null box, + std::shared_ptr call) { + box->setTitle(tr::lng_confcall_join_title()); + + box->addRow( + object_ptr( + box, + tr::lng_confcall_join_text(), + st::boxLabel)); + + box->addButton(tr::lng_confcall_join_button(), [=] { + + }); + box->addButton(tr::lng_cancel(), [=] { + box->closeBox(); + }); +} + } // namespace Calls::Group diff --git a/Telegram/SourceFiles/calls/group/calls_group_common.h b/Telegram/SourceFiles/calls/group/calls_group_common.h index 670378aa74..114c43e6d5 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_common.h +++ b/Telegram/SourceFiles/calls/group/calls_group_common.h @@ -11,6 +11,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL class UserData; +namespace Data { +class GroupCall; +} // namespace Data + namespace Ui { class GenericBox; } // namespace Ui @@ -93,4 +97,8 @@ using StickedTooltips = base::flags; [[nodiscard]] object_ptr ScreenSharingPrivacyRequestBox(); +void ConferenceCallJoinConfirm( + not_null box, + std::shared_ptr call); + } // namespace Calls::Group diff --git a/Telegram/SourceFiles/core/local_url_handlers.cpp b/Telegram/SourceFiles/core/local_url_handlers.cpp index 76a4c1aba7..f689603ec9 100644 --- a/Telegram/SourceFiles/core/local_url_handlers.cpp +++ b/Telegram/SourceFiles/core/local_url_handlers.cpp @@ -1448,6 +1448,21 @@ bool ResolveUniqueGift( return true; } +bool ResolveConferenceCall( + Window::SessionController *controller, + const Match &match, + const QVariant &context) { + if (!controller) { + return false; + } + const auto slug = match->captured(1); + if (slug.isEmpty()) { + return false; + } + controller->window().activate(); + controller->resolveConferenceCall(match->captured(1)); + return true; +} } // namespace const std::vector &LocalUrlHandlers() { @@ -1544,6 +1559,10 @@ const std::vector &LocalUrlHandlers() { u"^nft/?\\?slug=([a-zA-Z0-9\\.\\_\\-]+)(&|$)"_q, ResolveUniqueGift }, + { + u"^call/?\\?slug=([a-zA-Z0-9\\.\\_\\-]+)(&|$)"_q, + ResolveConferenceCall + }, { u"^([^\\?]+)(\\?|#|$)"_q, HandleUnknown @@ -1704,6 +1723,9 @@ QString TryConvertUrlToLocal(QString url) { } else if (const auto nftMatch = regex_match(u"^nft/([a-zA-Z0-9\\.\\_\\-]+)(\\?|$)"_q, query, matchOptions)) { const auto slug = nftMatch->captured(1); return u"tg://nft?slug="_q + slug; + } else if (const auto callMatch = regex_match(u"^call/([a-zA-Z0-9\\.\\_\\-]+)(\\?|$)"_q, query, matchOptions)) { + const auto slug = callMatch->captured(1); + return u"tg://call?slug="_q + slug; } else if (const auto privateMatch = regex_match(u"^" "c/(\\-?\\d+)" "(" diff --git a/Telegram/SourceFiles/data/data_channel.cpp b/Telegram/SourceFiles/data/data_channel.cpp index a4f4092e8b..d1a99f90b3 100644 --- a/Telegram/SourceFiles/data/data_channel.cpp +++ b/Telegram/SourceFiles/data/data_channel.cpp @@ -1005,6 +1005,8 @@ void ChannelData::setGroupCall( owner().registerGroupCall(_call.get()); session().changes().peerUpdated(this, UpdateFlag::GroupCall); addFlags(Flag::CallActive); + }, [&](const MTPDinputGroupCallSlug &) { + clearGroupCall(); }); } diff --git a/Telegram/SourceFiles/data/data_chat.cpp b/Telegram/SourceFiles/data/data_chat.cpp index 6f285e805f..faea166b1d 100644 --- a/Telegram/SourceFiles/data/data_chat.cpp +++ b/Telegram/SourceFiles/data/data_chat.cpp @@ -238,6 +238,8 @@ void ChatData::setGroupCall( owner().registerGroupCall(_call.get()); session().changes().peerUpdated(this, UpdateFlag::GroupCall); addFlags(Flag::CallActive); + }, [&](const MTPDinputGroupCallSlug &) { + clearGroupCall(); }); } diff --git a/Telegram/SourceFiles/data/data_group_call.cpp b/Telegram/SourceFiles/data/data_group_call.cpp index 0cc71299bb..c30eaeebaa 100644 --- a/Telegram/SourceFiles/data/data_group_call.cpp +++ b/Telegram/SourceFiles/data/data_group_call.cpp @@ -60,7 +60,7 @@ bool GroupCallParticipant::screenPaused() const { GroupCall::GroupCall( not_null peer, CallId id, - CallId accessHash, + uint64 accessHash, TimeId scheduleDate, bool rtmp) : _id(id) diff --git a/Telegram/SourceFiles/data/data_group_call.h b/Telegram/SourceFiles/data/data_group_call.h index 6dbaf8debe..8b7d16158d 100644 --- a/Telegram/SourceFiles/data/data_group_call.h +++ b/Telegram/SourceFiles/data/data_group_call.h @@ -56,7 +56,7 @@ public: GroupCall( not_null peer, CallId id, - CallId accessHash, + uint64 accessHash, TimeId scheduleDate, bool rtmp); ~GroupCall(); @@ -201,7 +201,7 @@ private: [[nodiscard]] Participant *findParticipant(not_null peer); const CallId _id = 0; - const CallId _accessHash = 0; + const uint64 _accessHash = 0; not_null _peer; int _version = 0; diff --git a/Telegram/SourceFiles/export/data/export_data_types.cpp b/Telegram/SourceFiles/export/data/export_data_types.cpp index 830e64e907..e9a91b434f 100644 --- a/Telegram/SourceFiles/export/data/export_data_types.cpp +++ b/Telegram/SourceFiles/export/data/export_data_types.cpp @@ -1713,6 +1713,12 @@ ServiceAction ParseServiceAction( result.content = ActionPaidMessagesPrice{ .stars = int(data.vstars().v), }; + }, [&](const MTPDmessageActionConferenceCall &data) { + result.content = ActionConferenceCall{ + .duration = data.vduration().value_or_empty(), + .active = data.is_active(), + .missed = data.is_missed(), + }; }, [](const MTPDmessageActionEmpty &data) {}); return result; } diff --git a/Telegram/SourceFiles/export/data/export_data_types.h b/Telegram/SourceFiles/export/data/export_data_types.h index a7518ba056..afdf7251bf 100644 --- a/Telegram/SourceFiles/export/data/export_data_types.h +++ b/Telegram/SourceFiles/export/data/export_data_types.h @@ -671,6 +671,12 @@ struct ActionPaidMessagesPrice { int stars = 0; }; +struct ActionConferenceCall { + int duration = 0; + bool active = false; + bool missed = false; +}; + struct ServiceAction { std::variant< v::null_t, @@ -718,7 +724,8 @@ struct ServiceAction { ActionPrizeStars, ActionStarGift, ActionPaidMessagesRefunded, - ActionPaidMessagesPrice> content; + ActionPaidMessagesPrice, + ActionConferenceCall> content; }; ServiceAction ParseServiceAction( diff --git a/Telegram/SourceFiles/export/output/export_output_html.cpp b/Telegram/SourceFiles/export/output/export_output_html.cpp index 7aada39659..29f7d734a7 100644 --- a/Telegram/SourceFiles/export/output/export_output_html.cpp +++ b/Telegram/SourceFiles/export/output/export_output_html.cpp @@ -1387,6 +1387,16 @@ auto HtmlWriter::Wrap::pushMessage( + QString::number(data.stars).toUtf8() + " Telegram Stars."; return result; + }, [&](const ActionConferenceCall &data) { + return data.missed + ? "Missed conference call" + : data.active + ? "Ongoing conference call" + : data.duration + ? "Conference call (" + + NumberToString(data.duration) + + " seconds)" + : "Declined conference call"; }, [](v::null_t) { return QByteArray(); }); if (!serviceText.isEmpty()) { diff --git a/Telegram/SourceFiles/export/output/export_output_json.cpp b/Telegram/SourceFiles/export/output/export_output_json.cpp index 1f482db782..e8d083dfb7 100644 --- a/Telegram/SourceFiles/export/output/export_output_json.cpp +++ b/Telegram/SourceFiles/export/output/export_output_json.cpp @@ -672,6 +672,12 @@ QByteArray SerializeMessage( pushActor(); pushAction("paid_messages_price_change"); push("price_stars", data.stars); + }, [&](const ActionConferenceCall &data) { + pushActor(); + pushAction("conference_call"); + push("duration_seconds", data.duration); + push("is_missed", data.missed); + push("is_active", data.active); }, [](v::null_t) {}); if (v::is_null(message.action.content)) { diff --git a/Telegram/SourceFiles/history/history_item.cpp b/Telegram/SourceFiles/history/history_item.cpp index 86861abed7..dd80c64291 100644 --- a/Telegram/SourceFiles/history/history_item.cpp +++ b/Telegram/SourceFiles/history/history_item.cpp @@ -5624,6 +5624,19 @@ void HistoryItem::setServiceMessageByAction(const MTPmessageAction &action) { return result; }; + auto prepareConferenceCall = [&](const MTPDmessageActionConferenceCall &action) { + auto result = PreparedServiceText(); + const auto duration = action.vduration().value_or_empty(); + result.text.text = action.is_missed() + ? tr::lng_action_confcall_missed(tr::now) + : action.is_active() + ? tr::lng_action_confcall_ongoing(tr::now) + : duration + ? tr::lng_action_confcall_finished(tr::now) + : tr::lng_action_confcall_invitation(tr::now); + return result; + }; + setServiceText(action.match( prepareChatAddUserText, prepareChatJoinedByLink, @@ -5673,6 +5686,7 @@ void HistoryItem::setServiceMessageByAction(const MTPmessageAction &action) { prepareStarGiftUnique, preparePaidMessagesRefunded, preparePaidMessagesPrice, + prepareConferenceCall, PrepareEmptyText, PrepareErrorText)); diff --git a/Telegram/SourceFiles/history/history_item_helpers.cpp b/Telegram/SourceFiles/history/history_item_helpers.cpp index 974fdbd8b8..0cd2a21733 100644 --- a/Telegram/SourceFiles/history/history_item_helpers.cpp +++ b/Telegram/SourceFiles/history/history_item_helpers.cpp @@ -915,6 +915,8 @@ MediaCheckResult CheckMessageMedia(const MTPMessageMedia &media) { [[nodiscard]] CallId CallIdFromInput(const MTPInputGroupCall &data) { return data.match([&](const MTPDinputGroupCall &data) { return data.vid().v; + }, [](const MTPDinputGroupCallSlug &) -> CallId { + Unexpected("inputGroupCallSlug in CallIdFromInput."); }); } diff --git a/Telegram/SourceFiles/mtproto/scheme/api.tl b/Telegram/SourceFiles/mtproto/scheme/api.tl index 37fb71c23f..ec6d3baef5 100644 --- a/Telegram/SourceFiles/mtproto/scheme/api.tl +++ b/Telegram/SourceFiles/mtproto/scheme/api.tl @@ -187,6 +187,7 @@ messageActionStarGift#4717e8a4 flags:# name_hidden:flags.0?true saved:flags.2?tr messageActionStarGiftUnique#acdfcb81 flags:# upgrade:flags.0?true transferred:flags.1?true saved:flags.2?true refunded:flags.5?true gift:StarGift can_export_at:flags.3?int transfer_stars:flags.4?long from_id:flags.6?Peer peer:flags.7?Peer saved_id:flags.7?long = MessageAction; messageActionPaidMessagesRefunded#ac1f1fcd count:int stars:long = MessageAction; messageActionPaidMessagesPrice#bcd71419 stars:long = MessageAction; +messageActionConferenceCall#ff397dea flags:# missed:flags.0?true active:flags.1?true call_id:long slug:string duration:flags.2?int other_participants:flags.3?Vector = MessageAction; dialog#d58a08c6 flags:# pinned:flags.2?true unread_mark:flags.3?true view_forum_as_messages:flags.6?true peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int unread_reactions_count:int notify_settings:PeerNotifySettings pts:flags.0?int draft:flags.1?DraftMessage folder_id:flags.4?int ttl_period:flags.5?int = Dialog; dialogFolder#71bd134c flags:# pinned:flags.2?true folder:Folder peer:Peer top_message:int unread_muted_peers_count:int unread_unmuted_peers_count:int unread_muted_messages_count:int unread_unmuted_messages_count:int = Dialog; @@ -431,6 +432,7 @@ updateStarsRevenueStatus#a584b019 peer:Peer status:StarsRevenueStatus = Update; updateBotPurchasedPaidMedia#283bd312 user_id:long payload:string qts:int = Update; updatePaidReactionPrivacy#8b725fce private:PaidReactionPrivacy = Update; updateSentPhoneCode#504aa18f sent_code:auth.SentCode = Update; +updateGroupCallChainBlocks#a477288f call:InputGroupCall sub_chain_id:int blocks:Vector next_offset:int = Update; updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State; @@ -1340,11 +1342,12 @@ peerBlocked#e8fd8014 peer_id:Peer date:int = PeerBlocked; stats.messageStats#7fe91c14 views_graph:StatsGraph reactions_by_emotion_graph:StatsGraph = stats.MessageStats; groupCallDiscarded#7780bcb4 id:long access_hash:long duration:int = GroupCall; -groupCall#cdf8d3e3 flags:# join_muted:flags.1?true can_change_join_muted:flags.2?true join_date_asc:flags.6?true schedule_start_subscribed:flags.8?true can_start_video:flags.9?true record_video_active:flags.11?true rtmp_stream:flags.12?true listeners_hidden:flags.13?true id:long access_hash:long participants_count:int title:flags.3?string stream_dc_id:flags.4?int record_start_date:flags.5?int schedule_date:flags.7?int unmuted_video_count:flags.10?int unmuted_video_limit:int version:int conference_from_call:flags.14?long = GroupCall; +groupCall#d597650c flags:# join_muted:flags.1?true can_change_join_muted:flags.2?true join_date_asc:flags.6?true schedule_start_subscribed:flags.8?true can_start_video:flags.9?true record_video_active:flags.11?true rtmp_stream:flags.12?true listeners_hidden:flags.13?true conference:flags.14?true id:long access_hash:long participants_count:int title:flags.3?string stream_dc_id:flags.4?int record_start_date:flags.5?int schedule_date:flags.7?int unmuted_video_count:flags.10?int unmuted_video_limit:int version:int = GroupCall; inputGroupCall#d8aa840f id:long access_hash:long = InputGroupCall; +inputGroupCallSlug#fe06823f slug:string = InputGroupCall; -groupCallParticipant#eba636fe flags:# muted:flags.0?true left:flags.1?true can_self_unmute:flags.2?true just_joined:flags.4?true versioned:flags.5?true min:flags.8?true muted_by_you:flags.9?true volume_by_admin:flags.10?true self:flags.12?true video_joined:flags.15?true peer:Peer date:int active_date:flags.3?int source:int volume:flags.7?int about:flags.11?string raise_hand_rating:flags.13?long video:flags.6?GroupCallParticipantVideo presentation:flags.14?GroupCallParticipantVideo = GroupCallParticipant; +groupCallParticipant#23860077 flags:# muted:flags.0?true left:flags.1?true can_self_unmute:flags.2?true just_joined:flags.4?true versioned:flags.5?true min:flags.8?true muted_by_you:flags.9?true volume_by_admin:flags.10?true self:flags.12?true video_joined:flags.15?true peer:Peer date:int active_date:flags.3?int source:int volume:flags.7?int about:flags.11?string raise_hand_rating:flags.13?long video:flags.6?GroupCallParticipantVideo presentation:flags.14?GroupCallParticipantVideo public_key:flags.16?int256 = GroupCallParticipant; phone.groupCall#9e727aad call:GroupCall participants:Vector participants_next_offset:string chats:Vector users:Vector = phone.GroupCall; @@ -2582,7 +2585,7 @@ phone.setCallRating#59ead627 flags:# user_initiative:flags.0?true peer:InputPhon phone.saveCallDebug#277add7e peer:InputPhoneCall debug:DataJSON = Bool; phone.sendSignalingData#ff7a9383 peer:InputPhoneCall data:bytes = Bool; phone.createGroupCall#48cdc6d8 flags:# rtmp_stream:flags.2?true peer:InputPeer random_id:int title:flags.0?string schedule_date:flags.1?int = Updates; -phone.joinGroupCall#d61e1df3 flags:# muted:flags.0?true video_stopped:flags.2?true call:InputGroupCall join_as:InputPeer invite_hash:flags.1?string key_fingerprint:flags.3?long params:DataJSON = Updates; +phone.joinGroupCall#ffae43f4 flags:# muted:flags.0?true video_stopped:flags.2?true call:InputGroupCall join_as:InputPeer invite_hash:flags.1?string public_key:flags.3?int256 invite_msg_id:flags.4?int params:DataJSON = Updates; phone.leaveGroupCall#500377f9 call:InputGroupCall source:int = Updates; phone.inviteToGroupCall#7b393160 call:InputGroupCall users:Vector = Updates; phone.discardGroupCall#7a777135 call:InputGroupCall = Updates; @@ -2603,7 +2606,13 @@ phone.leaveGroupCallPresentation#1c50d144 call:InputGroupCall = Updates; phone.getGroupCallStreamChannels#1ab21940 call:InputGroupCall = phone.GroupCallStreamChannels; phone.getGroupCallStreamRtmpUrl#deb3abbf peer:InputPeer revoke:Bool = phone.GroupCallStreamRtmpUrl; phone.saveCallLog#41248786 peer:InputPhoneCall file:InputFile = Bool; -phone.createConferenceCall#dfc909ab peer:InputPhoneCall key_fingerprint:long = phone.PhoneCall; +phone.createConferenceCall#dae2632f public_key:int256 zero_block:bytes = phone.GroupCall; +phone.addConferenceCallParticipant#3cb2a504 call:InputGroupCall peer:InputPeer block:bytes = Updates; +phone.deleteConferenceCallParticipant#7b8cc2a3 call:InputGroupCall peer:InputPeer block:bytes = Updates; +phone.sendConferenceCallBroadcast#c6701900 call:InputGroupCall block:bytes = Updates; +phone.inviteConferenceCallParticipant#3e9cf7ee call:InputGroupCall user_id:InputUser = Updates; +phone.declineConferenceCallInvite#3c479971 msg_id:int = Updates; +phone.getGroupCallChainBlocks#ee9f88a6 call:InputGroupCall sub_chain_id:int offset:int limit:int = Updates; langpack.getLangPack#f2f2330a lang_pack:string lang_code:string = LangPackDifference; langpack.getStrings#efea3803 lang_pack:string lang_code:string keys:Vector = Vector; @@ -2679,4 +2688,4 @@ smsjobs.finishJob#4f1ebf24 flags:# job_id:string error:flags.0?string = Bool; fragment.getCollectibleInfo#be1e85ba collectible:InputCollectible = fragment.CollectibleInfo; -// LAYER 201 +// LAYER 202 diff --git a/Telegram/SourceFiles/ui/image/image_location.cpp b/Telegram/SourceFiles/ui/image/image_location.cpp index d1fdde5b64..a10c6ba963 100644 --- a/Telegram/SourceFiles/ui/image/image_location.cpp +++ b/Telegram/SourceFiles/ui/image/image_location.cpp @@ -172,6 +172,8 @@ StorageFileLocation::StorageFileLocation( data.vcall().match([&](const MTPDinputGroupCall &data) { _id = data.vid().v; _accessHash = data.vaccess_hash().v; + }, [](const auto &data) { + Unexpected("inputGroupCallSlug in inputGroupCallStream."); }); _volumeId = data.vtime_ms().v; _localId = data.vscale().v; diff --git a/Telegram/SourceFiles/window/window_session_controller.cpp b/Telegram/SourceFiles/window/window_session_controller.cpp index ccdeaaa073..c4167c2ca8 100644 --- a/Telegram/SourceFiles/window/window_session_controller.cpp +++ b/Telegram/SourceFiles/window/window_session_controller.cpp @@ -72,6 +72,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/toast/toast.h" #include "calls/calls_instance.h" // Core::App().calls().inCall(). #include "calls/group/calls_group_call.h" +#include "calls/group/calls_group_common.h" #include "ui/boxes/calendar_box.h" #include "ui/boxes/collectible_info_box.h" #include "ui/boxes/confirm_box.h" @@ -816,10 +817,9 @@ void SessionNavigation::resolveCollectible( Fn fail) { if (_collectibleEntity == entity) { return; - } else { - _api.request(base::take(_collectibleRequestId)).cancel(); } _collectibleEntity = entity; + _api.request(base::take(_collectibleRequestId)).cancel(); _collectibleRequestId = _api.request(MTPfragment_GetCollectibleInfo( ((Ui::DetectCollectibleType(entity) == Ui::CollectibleType::Phone) ? MTP_inputCollectiblePhone(MTP_string(entity)) @@ -840,6 +840,39 @@ void SessionNavigation::resolveCollectible( }).send(); } +void SessionNavigation::resolveConferenceCall(const QString &slug) { + if (_conferenceCallSlug == slug) { + return; + } + _api.request(base::take(_conferenceCallRequestId)).cancel(); + _conferenceCallSlug = slug; + + const auto limit = 5; + _conferenceCallRequestId = _api.request(MTPphone_GetGroupCall( + MTP_inputGroupCallSlug(MTP_string(slug)), + MTP_int(limit) + )).done([=](const MTPphone_GroupCall &result) { + _conferenceCallRequestId = 0; + _conferenceCallSlug = QString(); + + result.data().vcall().match([&](const auto &data) { + const auto call = std::make_shared( + session().user(), + data.vid().v, + data.vaccess_hash().v, + TimeId(), // scheduleDate + false); // rtmp + call->processFullCall(result); + uiShow()->show( + Box(Calls::Group::ConferenceCallJoinConfirm, call)); + }); + }).fail([=] { + _conferenceCallRequestId = 0; + _conferenceCallSlug = QString(); + showToast(tr::lng_group_invite_bad_link(tr::now)); + }).send(); +} + void SessionNavigation::applyBoost( not_null channel, Fn done) { diff --git a/Telegram/SourceFiles/window/window_session_controller.h b/Telegram/SourceFiles/window/window_session_controller.h index 1fc2f0fe77..fd7056a1e0 100644 --- a/Telegram/SourceFiles/window/window_session_controller.h +++ b/Telegram/SourceFiles/window/window_session_controller.h @@ -264,6 +264,7 @@ public: PeerId ownerId, const QString &entity, Fn fail = nullptr); + void resolveConferenceCall(const QString &slug); base::weak_ptr showToast( Ui::Toast::Config &&config); @@ -329,6 +330,9 @@ private: QString _collectibleEntity; mtpRequestId _collectibleRequestId = 0; + QString _conferenceCallSlug; + mtpRequestId _conferenceCallRequestId = 0; + }; class SessionController : public SessionNavigation {