Update API scheme on layer 202.

This commit is contained in:
John Preston 2025-03-28 23:04:14 +05:00
parent 4401ea388c
commit 4eaf03b922
16 changed files with 123 additions and 81 deletions

View file

@ -678,14 +678,14 @@ void Instance::handleGroupCallUpdate(
}, [](const MTPDupdateGroupCallParticipants &data) { }, [](const MTPDupdateGroupCallParticipants &data) {
return data.vcall().match([&](const MTPDinputGroupCall &data) { return data.vcall().match([&](const MTPDinputGroupCall &data) {
return data.vid().v; return data.vid().v;
}, [](const MTPDinputGroupCallSlug &) -> CallId { }, [](const auto &) -> CallId {
Unexpected("slug in Instance::handleGroupCallUpdate"); Unexpected("slug/msg in Instance::handleGroupCallUpdate");
}); });
}, [](const MTPDupdateGroupCallChainBlocks &data) { }, [](const MTPDupdateGroupCallChainBlocks &data) {
return data.vcall().match([&](const MTPDinputGroupCall &data) { return data.vcall().match([&](const MTPDinputGroupCall &data) {
return data.vid().v; return data.vid().v;
}, [](const MTPDinputGroupCallSlug &) -> CallId { }, [](const auto &) -> CallId {
Unexpected("slug in Instance::handleGroupCallUpdate"); Unexpected("slug/msg in Instance::handleGroupCallUpdate");
}); });
}, [](const auto &) -> CallId { }, [](const auto &) -> CallId {
Unexpected("Type in Instance::handleGroupCallUpdate."); Unexpected("Type in Instance::handleGroupCallUpdate.");

View file

@ -715,44 +715,55 @@ void GroupCall::setupConferenceCall() {
sendOutboundBlock(std::move(block)); sendOutboundBlock(std::move(block));
}, _lifetime); }, _lifetime);
_conferenceCall->staleParticipantId( _conferenceCall->staleParticipantIds(
) | rpl::start_with_next([=](UserId staleId) { ) | rpl::start_with_next([=](const base::flat_set<UserId> &staleIds) {
removeConferenceParticipant(staleId); removeConferenceParticipants(staleIds);
}, _lifetime); }, _lifetime);
_e2e->participantsSetValue( _e2e->participantsSetValue(
) | rpl::start_with_next([=](const TdE2E::ParticipantsSet &set) { ) | rpl::start_with_next([=](const TdE2E::ParticipantsSet &set) {
auto users = base::flat_set<UserId>(); auto users = base::flat_set<UserId>();
users.reserve(set.list.size()); users.reserve(set.list.size());
auto ids = QStringList();
for (const auto &id : set.list) { for (const auto &id : set.list) {
users.emplace(UserId(id.v)); users.emplace(UserId(id.v));
ids.push_back('"' + _peer->owner().user(UserId(id.v))->name() + '"');
} }
LOG(("ACCESS: ") + ids.join(", "));
_conferenceCall->setParticipantsWithAccess(std::move(users)); _conferenceCall->setParticipantsWithAccess(std::move(users));
}, _lifetime); }, _lifetime);
} }
void GroupCall::removeConferenceParticipant(UserId id) { void GroupCall::removeConferenceParticipants(
const base::flat_set<UserId> userIds) {
Expects(_e2e != nullptr); Expects(_e2e != nullptr);
Expects(!userIds.empty());
const auto block = _e2e->makeRemoveBlock(TdE2E::MakeUserId(id)); const auto owner = &_peer->owner();
auto inputs = QVector<MTPInputPeer>();
inputs.reserve(userIds.size());
auto ids = base::flat_set<TdE2E::UserId>();
ids.reserve(userIds.size());
for (const auto &id : userIds) {
inputs.push_back(owner->user(id)->input);
ids.emplace(TdE2E::MakeUserId(id));
}
const auto block = _e2e->makeRemoveBlock(ids);
if (block.data.isEmpty()) { if (block.data.isEmpty()) {
return; return;
} }
_api.request(MTPphone_DeleteConferenceCallParticipant( _api.request(MTPphone_DeleteConferenceCallParticipants(
inputCall(), inputCall(),
_peer->owner().user(id)->input, MTP_vector<MTPInputPeer>(std::move(inputs)),
MTP_bytes(block.data) MTP_bytes(block.data)
)).done([=](const MTPUpdates &result) { )).done([=](const MTPUpdates &result) {
_peer->session().api().applyUpdates(result); _peer->session().api().applyUpdates(result);
}).fail([=](const MTP::Error &error) { }).fail([=](const MTP::Error &error) {
const auto type = error.type(); const auto type = error.type();
if (type == u"GROUPCALL_FORBIDDEN"_q) { if (type == u"GROUPCALL_FORBIDDEN"_q) {
setState(State::Joining); LOG(("Call Info: "
rejoin(); "Rejoin after error '%1' in delete confcall participants"
).arg(type));
startRejoin();
} else { } else {
LOG(("NOTREMOVED: %1").arg(type)); LOG(("Call Error: Could not remove confcall participants: %1"
).arg(type));
} }
}).send(); }).send();
} }
@ -1187,8 +1198,8 @@ void GroupCall::join(const MTPInputGroupCall &inputCall) {
inputCall.match([&](const MTPDinputGroupCall &data) { inputCall.match([&](const MTPDinputGroupCall &data) {
_id = data.vid().v; _id = data.vid().v;
_accessHash = data.vaccess_hash().v; _accessHash = data.vaccess_hash().v;
}, [&](const MTPDinputGroupCallSlug &) { }, [&](const auto &) {
Unexpected("inputGroupCallSlug in GroupCall::join."); Unexpected("slug/msg in GroupCall::join.");
}); });
setState(_scheduleDate ? State::Waiting : State::Joining); setState(_scheduleDate ? State::Waiting : State::Joining);
@ -1391,6 +1402,14 @@ void GroupCall::markTrackPaused(const VideoEndpoint &endpoint, bool paused) {
: Webrtc::VideoState::Active); : Webrtc::VideoState::Active);
} }
void GroupCall::startRejoin() {
for (const auto &[task, part] : _broadcastParts) {
_api.request(part.requestId).cancel();
}
setState(State::Joining);
rejoin();
}
void GroupCall::rejoin() { void GroupCall::rejoin() {
rejoin(joinAs()); rejoin(joinAs());
} }
@ -1489,10 +1508,7 @@ void GroupCall::sendJoinRequest() {
| (_e2e ? (Flag::f_public_key | Flag::f_block) : Flag()); | (_e2e ? (Flag::f_public_key | Flag::f_block) : Flag());
_api.request(MTPphone_JoinGroupCall( _api.request(MTPphone_JoinGroupCall(
MTP_flags(flags), MTP_flags(flags),
(_conferenceLinkSlug.isEmpty() inputCallSafe(),
? inputCall()
: MTP_inputGroupCallSlug(
MTP_string(_conferenceLinkSlug))),
joinAs()->input, joinAs()->input,
MTP_string(_joinHash), MTP_string(_joinHash),
(_e2e ? TdE2E::PublicKeyToMTP(_e2e->myKey()) : MTPint256()), (_e2e ? TdE2E::PublicKeyToMTP(_e2e->myKey()) : MTPint256()),
@ -1573,7 +1589,7 @@ void GroupCall::refreshLastBlockAndJoin() {
return; return;
} }
_api.request(MTPphone_GetGroupCallChainBlocks( _api.request(MTPphone_GetGroupCallChainBlocks(
inputCall(), inputCallSafe(),
MTP_int(0), MTP_int(0),
MTP_int(-1), MTP_int(-1),
MTP_int(1) MTP_int(1)
@ -1632,6 +1648,11 @@ void GroupCall::requestSubchainBlocks(int subchain, int height) {
auto &state = _subchains[subchain]; auto &state = _subchains[subchain];
state.requestId = 0; state.requestId = 0;
_e2e->subchainBlocksRequestFinished(subchain); _e2e->subchainBlocksRequestFinished(subchain);
if (error.type() == u"GROUPCALL_FORBIDDEN"_q) {
LOG(("Call Info: Rejoin after error '%1' in get chain blocks."
).arg(error.type()));
startRejoin();
}
}).send(); }).send();
} }
@ -1646,13 +1667,14 @@ void GroupCall::sendOutboundBlock(QByteArray block) {
const auto type = error.type(); const auto type = error.type();
if (type == u"GROUPCALL_FORBIDDEN"_q) { if (type == u"GROUPCALL_FORBIDDEN"_q) {
_pendingOutboundBlock = block; _pendingOutboundBlock = block;
setState(State::Joining); LOG(("Call Info: Rejoin after error '%1' in send confcall block."
rejoin(); ).arg(type));
startRejoin();
} else if (type == u"BLOCK_INVALID"_q } else if (type == u"BLOCK_INVALID"_q
|| type.startsWith(u"CONF_WRITE_CHAIN_INVALID"_q)) { || type.startsWith(u"CONF_WRITE_CHAIN_INVALID"_q)) {
LOG(("Call Error: Could not broadcast block: %1").arg(type)); LOG(("Call Error: Could not broadcast block: %1").arg(type));
} else { } else {
LOG(("HMM")); LOG(("Call Error: Got '%1' in send confcall block.").arg(type));
sendOutboundBlock(block); sendOutboundBlock(block);
} }
}).send(); }).send();
@ -2196,8 +2218,8 @@ void GroupCall::handleUpdate(const MTPDupdateGroupCallParticipants &data) {
const auto callId = data.vcall().match([]( const auto callId = data.vcall().match([](
const MTPDinputGroupCall &data) { const MTPDinputGroupCall &data) {
return data.vid().v; return data.vid().v;
}, [](const MTPDinputGroupCallSlug &) -> CallId { }, [](const auto &) -> CallId {
Unexpected("inputGroupCallSlug in GroupCall::handleUpdate."); Unexpected("slug/msg in GroupCall::handleUpdate.");
}); });
if (_id != callId) { if (_id != callId) {
return; return;
@ -2225,8 +2247,8 @@ void GroupCall::handleUpdate(const MTPDupdateGroupCallChainBlocks &data) {
const auto callId = data.vcall().match([]( const auto callId = data.vcall().match([](
const MTPDinputGroupCall &data) { const MTPDinputGroupCall &data) {
return data.vid().v; return data.vid().v;
}, [](const MTPDinputGroupCallSlug &) -> CallId { }, [](const auto &) -> CallId {
Unexpected("inputGroupCallSlug in GroupCall::handleUpdate."); Unexpected("slug/msg in GroupCall::handleUpdate.");
}); });
if (_id != callId || !_e2e) { if (_id != callId || !_e2e) {
return; return;
@ -2279,8 +2301,7 @@ void GroupCall::applySelfUpdate(const MTPDgroupCallParticipant &data) {
// I was removed from the call, rejoin. // I was removed from the call, rejoin.
LOG(("Call Info: " LOG(("Call Info: "
"Rejoin after got 'left' with my ssrc.")); "Rejoin after got 'left' with my ssrc."));
setState(State::Joining); startRejoin();
rejoin();
} }
return; return;
} else if (data.vsource().v != _joinState.ssrc) { } else if (data.vsource().v != _joinState.ssrc) {
@ -2307,8 +2328,7 @@ void GroupCall::applySelfUpdate(const MTPDgroupCallParticipant &data) {
: MuteState::ForceMuted); : MuteState::ForceMuted);
} else if (_instanceMode == InstanceMode::Stream) { } else if (_instanceMode == InstanceMode::Stream) {
LOG(("Call Info: Rejoin after unforcemute in stream mode.")); LOG(("Call Info: Rejoin after unforcemute in stream mode."));
setState(State::Joining); startRejoin();
rejoin();
} else if (mutedByAdmin()) { } else if (mutedByAdmin()) {
setMuted(MuteState::Muted); setMuted(MuteState::Muted);
if (!_instanceTransitioning) { if (!_instanceTransitioning) {
@ -2882,11 +2902,7 @@ void GroupCall::broadcastPartStart(std::shared_ptr<LoadPartTask> task) {
}).fail([=](const MTP::Error &error, const MTP::Response &response) { }).fail([=](const MTP::Error &error, const MTP::Response &response) {
if (error.type() == u"GROUPCALL_JOIN_MISSING"_q if (error.type() == u"GROUPCALL_JOIN_MISSING"_q
|| error.type() == u"GROUPCALL_FORBIDDEN"_q) { || error.type() == u"GROUPCALL_FORBIDDEN"_q) {
for (const auto &[task, part] : _broadcastParts) { startRejoin();
_api.request(part.requestId).cancel();
}
setState(State::Joining);
rejoin();
return; return;
} }
const auto status = (MTP::IsFloodError(error) const auto status = (MTP::IsFloodError(error)
@ -3005,11 +3021,7 @@ void GroupCall::requestCurrentTimeStart(
if (error.type() == u"GROUPCALL_JOIN_MISSING"_q if (error.type() == u"GROUPCALL_JOIN_MISSING"_q
|| error.type() == u"GROUPCALL_FORBIDDEN"_q) { || error.type() == u"GROUPCALL_FORBIDDEN"_q) {
for (const auto &[task, part] : _broadcastParts) { startRejoin();
_api.request(part.requestId).cancel();
}
setState(State::Joining);
rejoin();
} }
}).handleAllErrors().toDC( }).handleAllErrors().toDC(
MTP::groupCallStreamDcId(_broadcastDcId) MTP::groupCallStreamDcId(_broadcastDcId)
@ -3415,7 +3427,7 @@ void GroupCall::checkJoined() {
}).fail([=](const MTP::Error &error) { }).fail([=](const MTP::Error &error) {
LOG(("Call Info: Full rejoin after error '%1' in checkGroupCall." LOG(("Call Info: Full rejoin after error '%1' in checkGroupCall."
).arg(error.type())); ).arg(error.type()));
rejoin(); startRejoin();
}).send(); }).send();
} }
@ -3590,7 +3602,7 @@ void GroupCall::sendSelfUpdate(SendUpdateType type) {
if (error.type() == u"GROUPCALL_FORBIDDEN"_q) { if (error.type() == u"GROUPCALL_FORBIDDEN"_q) {
LOG(("Call Info: Rejoin after error '%1' in editGroupCallMember." LOG(("Call Info: Rejoin after error '%1' in editGroupCallMember."
).arg(error.type())); ).arg(error.type()));
rejoin(); startRejoin();
} }
}).send(); }).send();
} }
@ -3684,7 +3696,7 @@ void GroupCall::editParticipant(
if (error.type() == u"GROUPCALL_FORBIDDEN"_q) { if (error.type() == u"GROUPCALL_FORBIDDEN"_q) {
LOG(("Call Info: Rejoin after error '%1' in editGroupCallMember." LOG(("Call Info: Rejoin after error '%1' in editGroupCallMember."
).arg(error.type())); ).arg(error.type()));
rejoin(); startRejoin();
} }
}).send(); }).send();
} }
@ -3700,7 +3712,7 @@ std::variant<int, not_null<UserData*>> GroupCall::inviteUsers(
if (_conferenceCall) { if (_conferenceCall) {
for (const auto &user : users) { for (const auto &user : users) {
_api.request(MTPphone_InviteConferenceCallParticipant( _api.request(MTPphone_InviteConferenceCallParticipant(
inputCall(), inputCallSafe(),
user->inputUser user->inputUser
)).send(); )).send();
} }
@ -3821,9 +3833,16 @@ auto GroupCall::otherParticipantStateValue() const
MTPInputGroupCall GroupCall::inputCall() const { MTPInputGroupCall GroupCall::inputCall() const {
Expects(_id != 0); Expects(_id != 0);
return MTP_inputGroupCall( return MTP_inputGroupCall(MTP_long(_id), MTP_long(_accessHash));
MTP_long(_id), }
MTP_long(_accessHash));
MTPInputGroupCall GroupCall::inputCallSafe() const {
const auto inviteMsgId = _conferenceJoinMessageId.bare;
return inviteMsgId
? MTP_inputGroupCallInviteMessage(MTP_int(inviteMsgId))
: _conferenceLinkSlug.isEmpty()
? inputCall()
: MTP_inputGroupCallSlug(MTP_string(_conferenceLinkSlug));
} }
void GroupCall::destroyController() { void GroupCall::destroyController() {

View file

@ -281,7 +281,7 @@ public:
void startScheduledNow(); void startScheduledNow();
void toggleScheduleStartSubscribed(bool subscribed); void toggleScheduleStartSubscribed(bool subscribed);
void setNoiseSuppression(bool enabled); void setNoiseSuppression(bool enabled);
void removeConferenceParticipant(UserId userId); void removeConferenceParticipants(const base::flat_set<UserId> userIds);
bool emitShareScreenError(); bool emitShareScreenError();
bool emitShareCameraError(); bool emitShareCameraError();
@ -545,6 +545,7 @@ private:
const std::optional<Data::GroupCallParticipant> &was, const std::optional<Data::GroupCallParticipant> &was,
const Data::GroupCallParticipant &now); const Data::GroupCallParticipant &now);
void applyMeInCallLocally(); void applyMeInCallLocally();
void startRejoin();
void rejoin(); void rejoin();
void leave(); void leave();
void rejoin(not_null<PeerData*> as); void rejoin(not_null<PeerData*> as);
@ -615,6 +616,7 @@ private:
[[nodiscard]] int activeVideoSendersCount() const; [[nodiscard]] int activeVideoSendersCount() const;
[[nodiscard]] MTPInputGroupCall inputCall() const; [[nodiscard]] MTPInputGroupCall inputCall() const;
[[nodiscard]] MTPInputGroupCall inputCallSafe() const;
const not_null<Delegate*> _delegate; const not_null<Delegate*> _delegate;
const std::shared_ptr<Data::GroupCall> _conferenceCall; const std::shared_ptr<Data::GroupCall> _conferenceCall;

View file

@ -1006,7 +1006,7 @@ void ChannelData::setGroupCall(
owner().registerGroupCall(_call.get()); owner().registerGroupCall(_call.get());
session().changes().peerUpdated(this, UpdateFlag::GroupCall); session().changes().peerUpdated(this, UpdateFlag::GroupCall);
addFlags(Flag::CallActive); addFlags(Flag::CallActive);
}, [&](const MTPDinputGroupCallSlug &) { }, [&](const auto &) {
clearGroupCall(); clearGroupCall();
}); });
} }

View file

@ -239,7 +239,7 @@ void ChatData::setGroupCall(
owner().registerGroupCall(_call.get()); owner().registerGroupCall(_call.get());
session().changes().peerUpdated(this, UpdateFlag::GroupCall); session().changes().peerUpdated(this, UpdateFlag::GroupCall);
addFlags(Flag::CallActive); addFlags(Flag::CallActive);
}, [&](const MTPDinputGroupCallSlug &) { }, [&](const auto &) {
clearGroupCall(); clearGroupCall();
}); });
} }

View file

@ -85,7 +85,7 @@ GroupCall::GroupCall(
}) | rpl::start_with_next([=](const ParticipantUpdate &update) { }) | rpl::start_with_next([=](const ParticipantUpdate &update) {
if (const auto id = peerToUser(update.was->peer->id)) { if (const auto id = peerToUser(update.was->peer->id)) {
if (_participantsWithAccess.current().contains(id)) { if (_participantsWithAccess.current().contains(id)) {
_staleParticipantId.fire_copy(id); _staleParticipantIds.fire({ id });
} }
} }
}, _checkStaleLifetime); }, _checkStaleLifetime);
@ -262,12 +262,16 @@ void GroupCall::checkStaleRequest() {
existing.emplace(id); existing.emplace(id);
} }
} }
auto stale = base::flat_set<UserId>();
for (const auto &id : list) { for (const auto &id : list) {
if (!existing.contains(id)) { if (!existing.contains(id)) {
_staleParticipantId.fire_copy(id); stale.reserve(list.size());
return; stale.emplace(id);
} }
} }
if (!stale.empty()) {
_staleParticipantIds.fire(std::move(stale));
}
}).fail([=] { }).fail([=] {
_checkStaleRequestId = 0; _checkStaleRequestId = 0;
}).send(); }).send();
@ -402,8 +406,9 @@ auto GroupCall::participantsWithAccessValue() const
return _participantsWithAccess.value(); return _participantsWithAccess.value();
} }
rpl::producer<UserId> GroupCall::staleParticipantId() const { auto GroupCall::staleParticipantIds() const
return _staleParticipantId.events(); -> rpl::producer<base::flat_set<UserId>> {
return _staleParticipantIds.events();
} }
void GroupCall::enqueueUpdate(const MTPUpdate &update) { void GroupCall::enqueueUpdate(const MTPUpdate &update) {

View file

@ -150,7 +150,8 @@ public:
-> const base::flat_set<UserId> &; -> const base::flat_set<UserId> &;
[[nodiscard]] auto participantsWithAccessValue() const [[nodiscard]] auto participantsWithAccessValue() const
-> rpl::producer<base::flat_set<UserId>>; -> rpl::producer<base::flat_set<UserId>>;
[[nodiscard]] rpl::producer<UserId> staleParticipantId() const; [[nodiscard]] auto staleParticipantIds() const
-> rpl::producer<base::flat_set<UserId>>;
void setParticipantsLoaded(); void setParticipantsLoaded();
void checkStaleParticipants(); void checkStaleParticipants();
void checkStaleRequest(); void checkStaleRequest();
@ -264,7 +265,7 @@ private:
rpl::event_stream<> _participantsReloaded; rpl::event_stream<> _participantsReloaded;
rpl::variable<base::flat_set<UserId>> _participantsWithAccess; rpl::variable<base::flat_set<UserId>> _participantsWithAccess;
rpl::event_stream<UserId> _staleParticipantId; rpl::event_stream<base::flat_set<UserId>> _staleParticipantIds;
mtpRequestId _checkStaleRequestId = 0; mtpRequestId _checkStaleRequestId = 0;
rpl::lifetime _checkStaleLifetime; rpl::lifetime _checkStaleLifetime;

View file

@ -1227,9 +1227,9 @@ void History::applyServiceChanges(
} }
} }
}, [&](const MTPDmessageActionConferenceCall &data) { }, [&](const MTPDmessageActionConferenceCall &data) {
if (!data.is_active() && !data.is_missed()) { if (!data.is_active() && !data.is_missed() && !item->out()) {
if (const auto window = session().tryResolveWindow()) { if (const auto window = session().tryResolveWindow()) {
window->resolveConferenceCall(qs(data.vslug()), item->id); window->resolveConferenceCall(item->id);
} }
} }
}, [](const auto &) { }, [](const auto &) {

View file

@ -5640,13 +5640,12 @@ void HistoryItem::setServiceMessageByAction(const MTPmessageAction &action) {
} }
const auto id = this->id; const auto id = this->id;
const auto slug = qs(action.vslug());
setCustomServiceLink(std::make_shared<LambdaClickHandler>([=]( setCustomServiceLink(std::make_shared<LambdaClickHandler>([=](
ClickContext context) { ClickContext context) {
const auto my = context.other.value<ClickHandlerContext>(); const auto my = context.other.value<ClickHandlerContext>();
const auto weak = my.sessionWindow; const auto weak = my.sessionWindow;
if (const auto strong = weak.get()) { if (const auto strong = weak.get()) {
strong->resolveConferenceCall(slug, id); strong->resolveConferenceCall(id);
} }
})); }));

View file

@ -915,8 +915,8 @@ MediaCheckResult CheckMessageMedia(const MTPMessageMedia &media) {
[[nodiscard]] CallId CallIdFromInput(const MTPInputGroupCall &data) { [[nodiscard]] CallId CallIdFromInput(const MTPInputGroupCall &data) {
return data.match([&](const MTPDinputGroupCall &data) { return data.match([&](const MTPDinputGroupCall &data) {
return data.vid().v; return data.vid().v;
}, [](const MTPDinputGroupCallSlug &) -> CallId { }, [](const auto &) -> CallId {
Unexpected("inputGroupCallSlug in CallIdFromInput."); Unexpected("slug/msg in CallIdFromInput.");
}); });
} }

View file

@ -187,7 +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; 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; messageActionPaidMessagesRefunded#ac1f1fcd count:int stars:long = MessageAction;
messageActionPaidMessagesPrice#bcd71419 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<Peer> = MessageAction; messageActionConferenceCall#2ffe2f7a flags:# missed:flags.0?true active:flags.1?true call_id:long duration:flags.2?int other_participants:flags.3?Vector<Peer> = 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; 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; 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;
@ -1346,6 +1346,7 @@ groupCall#d597650c flags:# join_muted:flags.1?true can_change_join_muted:flags.2
inputGroupCall#d8aa840f id:long access_hash:long = InputGroupCall; inputGroupCall#d8aa840f id:long access_hash:long = InputGroupCall;
inputGroupCallSlug#fe06823f slug:string = InputGroupCall; inputGroupCallSlug#fe06823f slug:string = InputGroupCall;
inputGroupCallInviteMessage#8c10603f msg_id:int = 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#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;
@ -2607,7 +2608,7 @@ phone.getGroupCallStreamChannels#1ab21940 call:InputGroupCall = phone.GroupCallS
phone.getGroupCallStreamRtmpUrl#deb3abbf peer:InputPeer revoke:Bool = phone.GroupCallStreamRtmpUrl; phone.getGroupCallStreamRtmpUrl#deb3abbf peer:InputPeer revoke:Bool = phone.GroupCallStreamRtmpUrl;
phone.saveCallLog#41248786 peer:InputPhoneCall file:InputFile = Bool; phone.saveCallLog#41248786 peer:InputPhoneCall file:InputFile = Bool;
phone.createConferenceCall#fbcefee6 random_id:int = phone.GroupCall; phone.createConferenceCall#fbcefee6 random_id:int = phone.GroupCall;
phone.deleteConferenceCallParticipant#7b8cc2a3 call:InputGroupCall peer:InputPeer block:bytes = Updates; phone.deleteConferenceCallParticipants#22e547c7 call:InputGroupCall ids:Vector<InputPeer> block:bytes = Updates;
phone.sendConferenceCallBroadcast#c6701900 call:InputGroupCall block:bytes = Updates; phone.sendConferenceCallBroadcast#c6701900 call:InputGroupCall block:bytes = Updates;
phone.inviteConferenceCallParticipant#3e9cf7ee call:InputGroupCall user_id:InputUser = Updates; phone.inviteConferenceCallParticipant#3e9cf7ee call:InputGroupCall user_id:InputUser = Updates;
phone.declineConferenceCallInvite#3c479971 msg_id:int = Updates; phone.declineConferenceCallInvite#3c479971 msg_id:int = Updates;

View file

@ -124,8 +124,8 @@ Block Call::makeJoinBlock() {
}; };
} }
Block Call::makeRemoveBlock(UserId id) { Block Call::makeRemoveBlock(const base::flat_set<UserId> &ids) {
if (failed() || !_id || id == _myUserId) { if (failed() || !_id) {
return {}; return {};
} }
@ -137,11 +137,13 @@ Block Call::makeRemoveBlock(UserId id) {
auto found = false; auto found = false;
auto updated = state.value(); auto updated = state.value();
auto &list = updated.participants; auto &list = updated.participants;
for (auto i = begin(list); i != end(list); ++i) { for (auto i = begin(list); i != end(list);) {
if (uint64(i->user_id) == id.v) { const auto userId = UserId{ uint64(i->user_id) };
list.erase(i); if (userId != _myUserId && ids.contains(userId)) {
i = list.erase(i);
found = true; found = true;
break; } else {
++i;
} }
} }
if (!found) { if (!found) {

View file

@ -97,7 +97,7 @@ public:
void refreshLastBlock0(std::optional<Block> block); void refreshLastBlock0(std::optional<Block> block);
[[nodiscard]] Block makeJoinBlock(); [[nodiscard]] Block makeJoinBlock();
[[nodiscard]] Block makeRemoveBlock(UserId id); [[nodiscard]] Block makeRemoveBlock(const base::flat_set<UserId> &ids);
[[nodiscard]] rpl::producer<ParticipantsSet> participantsSetValue() const; [[nodiscard]] rpl::producer<ParticipantsSet> participantsSetValue() const;

View file

@ -173,7 +173,7 @@ StorageFileLocation::StorageFileLocation(
_id = data.vid().v; _id = data.vid().v;
_accessHash = data.vaccess_hash().v; _accessHash = data.vaccess_hash().v;
}, [](const auto &data) { }, [](const auto &data) {
Unexpected("inputGroupCallSlug in inputGroupCallStream."); Unexpected("slug/msg in inputGroupCallStream.");
}); });
_volumeId = data.vtime_ms().v; _volumeId = data.vtime_ms().v;
_localId = data.vscale().v; _localId = data.vscale().v;

View file

@ -840,6 +840,14 @@ void SessionNavigation::resolveCollectible(
}).send(); }).send();
} }
void SessionNavigation::resolveConferenceCall(const QString &slug) {
resolveConferenceCall(slug, 0);
}
void SessionNavigation::resolveConferenceCall(MsgId inviteMsgId) {
resolveConferenceCall(QString(), inviteMsgId);
}
void SessionNavigation::resolveConferenceCall( void SessionNavigation::resolveConferenceCall(
const QString &slug, const QString &slug,
MsgId inviteMsgId) { MsgId inviteMsgId) {
@ -853,11 +861,14 @@ void SessionNavigation::resolveConferenceCall(
const auto limit = 5; const auto limit = 5;
_conferenceCallRequestId = _api.request(MTPphone_GetGroupCall( _conferenceCallRequestId = _api.request(MTPphone_GetGroupCall(
MTP_inputGroupCallSlug(MTP_string(slug)), (inviteMsgId
? MTP_inputGroupCallInviteMessage(MTP_int(inviteMsgId.bare))
: MTP_inputGroupCallSlug(MTP_string(slug))),
MTP_int(limit) MTP_int(limit)
)).done([=](const MTPphone_GroupCall &result) { )).done([=](const MTPphone_GroupCall &result) {
_conferenceCallRequestId = 0; _conferenceCallRequestId = 0;
const auto slug = base::take(_conferenceCallSlug); const auto slug = base::take(_conferenceCallSlug);
const auto inviteMsgId = base::take(_conferenceCallInviteMsgId);
result.data().vcall().match([&](const auto &data) { result.data().vcall().match([&](const auto &data) {
const auto call = std::make_shared<Data::GroupCall>( const auto call = std::make_shared<Data::GroupCall>(
@ -884,7 +895,7 @@ void SessionNavigation::resolveConferenceCall(
box->boxClosing() | rpl::start_with_next([=] { box->boxClosing() | rpl::start_with_next([=] {
if (inviteMsgId && !*confirmed) { if (inviteMsgId && !*confirmed) {
_api.request(MTPphone_DeclineConferenceCallInvite( _api.request(MTPphone_DeclineConferenceCallInvite(
MTP_int(inviteMsgId) MTP_int(inviteMsgId.bare)
)).send(); )).send();
} }
}, box->lifetime()); }, box->lifetime());

View file

@ -264,7 +264,8 @@ public:
PeerId ownerId, PeerId ownerId,
const QString &entity, const QString &entity,
Fn<void(QString)> fail = nullptr); Fn<void(QString)> fail = nullptr);
void resolveConferenceCall(const QString &slug, MsgId inviteMsgId = 0); void resolveConferenceCall(const QString &slug);
void resolveConferenceCall(MsgId inviteMsgId);
base::weak_ptr<Ui::Toast::Instance> showToast( base::weak_ptr<Ui::Toast::Instance> showToast(
Ui::Toast::Config &&config); Ui::Toast::Config &&config);
@ -291,6 +292,7 @@ private:
void resolveChannelById( void resolveChannelById(
ChannelId channelId, ChannelId channelId,
Fn<void(not_null<ChannelData*>)> done); Fn<void(not_null<ChannelData*>)> done);
void resolveConferenceCall(const QString &slug, MsgId inviteMsgId);
void resolveDone( void resolveDone(
const MTPcontacts_ResolvedPeer &result, const MTPcontacts_ResolvedPeer &result,