mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-03 21:54:05 +02:00
Support distinct calling/invited states.
This commit is contained in:
parent
55c05d1a6e
commit
b036bedbc3
16 changed files with 221 additions and 105 deletions
|
@ -4762,6 +4762,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
"lng_group_call_invite" = "Invite Members";
|
||||
"lng_group_call_invite_conf" = "Add People";
|
||||
"lng_group_call_invited_status" = "invited";
|
||||
"lng_group_call_calling_status" = "calling...";
|
||||
"lng_group_call_blockchain_only_status" = "listening";
|
||||
"lng_group_call_muted_by_me_status" = "muted for you";
|
||||
"lng_group_call_invite_title" = "Invite members";
|
||||
|
|
|
@ -893,6 +893,8 @@ groupCallMemberColoredCrossLine: CrossLineAnimation(groupCallMemberInactiveCross
|
|||
fg: groupCallMemberMutedIcon;
|
||||
icon: icon {{ "calls/group_calls_unmuted", groupCallMemberActiveIcon }};
|
||||
}
|
||||
groupCallMemberCalling: icon {{ "calls/call_answer", groupCallMemberInactiveIcon }};
|
||||
groupCallMemberCallingPosition: point(0px, 8px);
|
||||
groupCallMemberInvited: icon {{ "calls/group_calls_invited", groupCallMemberInactiveIcon }};
|
||||
groupCallMemberInvitedPosition: point(2px, 12px);
|
||||
groupCallMemberRaisedHand: icon {{ "calls/group_calls_raised_hand", groupCallMemberInactiveStatus }};
|
||||
|
@ -1327,6 +1329,7 @@ groupCallNarrowRaisedHand: icon {{ "calls/video_mini_speak", groupCallMemberInac
|
|||
groupCallNarrowCameraIcon: icon {{ "calls/video_mini_video", groupCallMemberNotJoinedStatus }};
|
||||
groupCallNarrowScreenIcon: icon {{ "calls/video_mini_screencast", groupCallMemberNotJoinedStatus }};
|
||||
groupCallNarrowInvitedIcon: icon {{ "calls/video_mini_invited", groupCallMemberNotJoinedStatus }};
|
||||
groupCallNarrowCallingIcon: icon {{ "calls/video_mini_invited", groupCallMemberNotJoinedStatus }};
|
||||
groupCallNarrowIconPosition: point(-4px, 2px);
|
||||
groupCallNarrowIconSkip: 15px;
|
||||
groupCallOutline: 2px;
|
||||
|
|
|
@ -1542,7 +1542,8 @@ void Call::finish(
|
|||
_user->owner().registerInvitedToCallUser(
|
||||
migrateCall->id(),
|
||||
migrateCall,
|
||||
_user);
|
||||
_user,
|
||||
true);
|
||||
}
|
||||
const auto session = &_user->session();
|
||||
const auto weak = base::make_weak(this);
|
||||
|
|
|
@ -930,7 +930,8 @@ void Instance::unregisterConferenceInvite(
|
|||
CallId conferenceId,
|
||||
not_null<UserData*> user,
|
||||
MsgId messageId,
|
||||
bool incoming) {
|
||||
bool incoming,
|
||||
bool onlyStopCalling) {
|
||||
const auto i = _conferenceInvites.find(conferenceId);
|
||||
if (i == end(_conferenceInvites)) {
|
||||
return;
|
||||
|
@ -940,9 +941,14 @@ void Instance::unregisterConferenceInvite(
|
|||
return;
|
||||
}
|
||||
auto &info = j->second;
|
||||
(incoming ? info.incoming : info.outgoing).remove(messageId);
|
||||
if (!(incoming ? info.incoming : info.outgoing).remove(messageId)) {
|
||||
return;
|
||||
}
|
||||
if (!incoming) {
|
||||
user->owner().unregisterInvitedToCallUser(conferenceId, user);
|
||||
user->owner().unregisterInvitedToCallUser(
|
||||
conferenceId,
|
||||
user,
|
||||
onlyStopCalling);
|
||||
}
|
||||
if (info.incoming.empty() && info.outgoing.empty()) {
|
||||
i->second.users.erase(j);
|
||||
|
@ -1010,6 +1016,11 @@ void Instance::declineOutgoingConferenceInvite(
|
|||
user->owner().history(user),
|
||||
std::move(inputs),
|
||||
true);
|
||||
for (const auto &messageId : ids) {
|
||||
if (const auto item = user->owner().message(user, messageId)) {
|
||||
item->destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!j->second.incoming.empty()) {
|
||||
return;
|
||||
|
@ -1018,7 +1029,7 @@ void Instance::declineOutgoingConferenceInvite(
|
|||
if (i->second.users.empty()) {
|
||||
_conferenceInvites.erase(i);
|
||||
}
|
||||
user->owner().unregisterInvitedToCallUser(conferenceId, user);
|
||||
user->owner().unregisterInvitedToCallUser(conferenceId, user, !discard);
|
||||
}
|
||||
|
||||
void Instance::showConferenceInvite(
|
||||
|
|
|
@ -131,7 +131,8 @@ public:
|
|||
CallId conferenceId,
|
||||
not_null<UserData*> user,
|
||||
MsgId messageId,
|
||||
bool incoming);
|
||||
bool incoming,
|
||||
bool onlyStopCalling = false);
|
||||
void showConferenceInvite(
|
||||
not_null<UserData*> user,
|
||||
MsgId conferenceInviteMsgId);
|
||||
|
|
|
@ -1623,6 +1623,9 @@ void GroupCall::sendJoinRequest() {
|
|||
if (const auto once = base::take(_migratedConferenceInfo)) {
|
||||
processMigration(*once);
|
||||
}
|
||||
for (const auto &callback : base::take(_rejoinedCallbacks)) {
|
||||
callback();
|
||||
}
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
const auto type = error.type();
|
||||
if (_e2e) {
|
||||
|
@ -3775,6 +3778,45 @@ void GroupCall::editParticipant(
|
|||
}).send();
|
||||
}
|
||||
|
||||
|
||||
void GroupCall::inviteToConference(
|
||||
InviteRequest request,
|
||||
Fn<not_null<InviteResult*>()> resultAddress,
|
||||
Fn<void()> finishRequest) {
|
||||
using Flag = MTPphone_InviteConferenceCallParticipant::Flag;
|
||||
const auto user = request.user;
|
||||
_api.request(MTPphone_InviteConferenceCallParticipant(
|
||||
MTP_flags(request.video ? Flag::f_video : Flag()),
|
||||
inputCall(),
|
||||
user->inputUser
|
||||
)).done([=](const MTPUpdates &result) {
|
||||
const auto call = _conferenceCall.get();
|
||||
user->owner().registerInvitedToCallUser(_id, call, user, true);
|
||||
_peer->session().api().applyUpdates(result);
|
||||
resultAddress()->invited.push_back(user);
|
||||
finishRequest();
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
const auto result = resultAddress();
|
||||
const auto type = error.type();
|
||||
if (type == u"USER_PRIVACY_RESTRICTED"_q) {
|
||||
result->privacyRestricted.push_back(user);
|
||||
} else if (type == u"USER_ALREADY_PARTICIPANT"_q) {
|
||||
result->alreadyIn.push_back(user);
|
||||
} else if (type == u"USER_WAS_KICKED"_q) {
|
||||
result->kicked.push_back(user);
|
||||
} else if (type == u"GROUPCALL_FORBIDDEN"_q) {
|
||||
startRejoin();
|
||||
_rejoinedCallbacks.push_back([=] {
|
||||
inviteToConference(request, resultAddress, finishRequest);
|
||||
});
|
||||
return;
|
||||
} else {
|
||||
result->failed.push_back(user);
|
||||
}
|
||||
finishRequest();
|
||||
}).send();
|
||||
}
|
||||
|
||||
void GroupCall::inviteUsers(
|
||||
const std::vector<InviteRequest> &requests,
|
||||
Fn<void(InviteResult)> done) {
|
||||
|
@ -3802,32 +3844,9 @@ void GroupCall::inviteUsers(
|
|||
|
||||
if (const auto call = _conferenceCall.get()) {
|
||||
for (const auto &request : requests) {
|
||||
using Flag = MTPphone_InviteConferenceCallParticipant::Flag;
|
||||
const auto user = request.user;
|
||||
_api.request(MTPphone_InviteConferenceCallParticipant(
|
||||
MTP_flags(request.video ? Flag::f_video : Flag()),
|
||||
inputCallSafe(),
|
||||
user->inputUser
|
||||
)).done([=](const MTPUpdates &result) {
|
||||
owner->registerInvitedToCallUser(_id, call, user);
|
||||
_peer->session().api().applyUpdates(result);
|
||||
state->result.invited.push_back(user);
|
||||
finishRequest();
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
const auto type = error.type();
|
||||
if (type == u"USER_PRIVACY_RESTRICTED"_q) {
|
||||
state->result.privacyRestricted.push_back(user);
|
||||
} else if (type == u"USER_ALREADY_PARTICIPANT"_q) {
|
||||
state->result.alreadyIn.push_back(user);
|
||||
} else if (type == u"USER_WAS_KICKED"_q) {
|
||||
state->result.kicked.push_back(user);
|
||||
} else if (type == u"GROUPCALL_FORBIDDEN"_q) {
|
||||
startRejoin();
|
||||
} else {
|
||||
state->result.failed.push_back(user);
|
||||
}
|
||||
finishRequest();
|
||||
}).send();
|
||||
inviteToConference(request, [=] {
|
||||
return &state->result;
|
||||
}, finishRequest);
|
||||
++state->requests;
|
||||
}
|
||||
return;
|
||||
|
@ -3857,7 +3876,7 @@ void GroupCall::inviteUsers(
|
|||
};
|
||||
for (const auto &request : requests) {
|
||||
const auto user = request.user;
|
||||
owner->registerInvitedToCallUser(_id, _peer, user);
|
||||
owner->registerInvitedToCallUser(_id, _peer, user, false);
|
||||
usersSlice.push_back(user);
|
||||
slice.push_back(user->inputUser);
|
||||
if (slice.size() == kMaxInvitePerSlice) {
|
||||
|
|
|
@ -625,6 +625,10 @@ private:
|
|||
void markTrackShown(const VideoEndpoint &endpoint, bool shown);
|
||||
|
||||
void processMigration(StartConferenceInfo conference);
|
||||
void inviteToConference(
|
||||
InviteRequest request,
|
||||
Fn<not_null<InviteResult*>()> resultAddress,
|
||||
Fn<void()> finishRequest);
|
||||
|
||||
[[nodiscard]] int activeVideoSendersCount() const;
|
||||
|
||||
|
@ -645,6 +649,7 @@ private:
|
|||
rpl::variable<State> _state = State::Creating;
|
||||
base::flat_set<uint32> _unresolvedSsrcs;
|
||||
rpl::event_stream<Error> _errors;
|
||||
std::vector<Fn<void()>> _rejoinedCallbacks;
|
||||
bool _recordingStoppedByMe = false;
|
||||
bool _requestedVideoChannelsUpdateScheduled = false;
|
||||
|
||||
|
|
|
@ -477,15 +477,23 @@ object_ptr<Ui::BoxContent> PrepareInviteBox(
|
|||
return nullptr;
|
||||
}
|
||||
const auto peer = call->peer();
|
||||
const auto conference = call->conference();
|
||||
const auto weak = base::make_weak(call);
|
||||
auto alreadyIn = peer->owner().invitedToCallUsers(real->id());
|
||||
const auto &invited = peer->owner().invitedToCallUsers(real->id());
|
||||
auto alreadyIn = base::flat_set<not_null<UserData*>>();
|
||||
alreadyIn.reserve(invited.size() + real->participants().size() + 1);
|
||||
alreadyIn.emplace(peer->session().user());
|
||||
for (const auto &participant : real->participants()) {
|
||||
if (const auto user = participant.peer->asUser()) {
|
||||
alreadyIn.emplace(user);
|
||||
}
|
||||
}
|
||||
alreadyIn.emplace(peer->session().user());
|
||||
if (call->conference()) {
|
||||
for (const auto &[user, calling] : invited) {
|
||||
if (!conference || calling) {
|
||||
alreadyIn.emplace(user);
|
||||
}
|
||||
}
|
||||
if (conference) {
|
||||
const auto close = std::make_shared<Fn<void()>>();
|
||||
const auto shareLink = [=] {
|
||||
Assert(shareConferenceLink != nullptr);
|
||||
|
|
|
@ -108,7 +108,8 @@ private:
|
|||
[[nodiscard]] std::unique_ptr<Row> createRow(
|
||||
const Data::GroupCallParticipant &participant);
|
||||
[[nodiscard]] std::unique_ptr<Row> createInvitedRow(
|
||||
not_null<PeerData*> participantPeer);
|
||||
not_null<PeerData*> participantPeer,
|
||||
bool calling);
|
||||
[[nodiscard]] std::unique_ptr<Row> createWithAccessRow(
|
||||
not_null<PeerData*> participantPeer);
|
||||
|
||||
|
@ -494,8 +495,9 @@ void Members::Controller::toggleVideoEndpointActive(
|
|||
bool Members::Controller::appendInvitedUsers() {
|
||||
auto changed = false;
|
||||
if (const auto id = _call->id()) {
|
||||
for (const auto &user : _peer->owner().invitedToCallUsers(id)) {
|
||||
if (auto row = createInvitedRow(user)) {
|
||||
const auto &invited = _peer->owner().invitedToCallUsers(id);
|
||||
for (const auto &[user, calling] : invited) {
|
||||
if (auto row = createInvitedRow(user, calling)) {
|
||||
delegate()->peerListAppendRow(std::move(row));
|
||||
changed = true;
|
||||
}
|
||||
|
@ -514,14 +516,16 @@ void Members::Controller::setupInvitedUsers() {
|
|||
) | rpl::filter([=](const Invite &invite) {
|
||||
return (invite.id == _call->id());
|
||||
}) | rpl::start_with_next([=](const Invite &invite) {
|
||||
const auto user = invite.user;
|
||||
if (invite.removed) {
|
||||
if (const auto row = findRow(invite.user)) {
|
||||
if (row->state() == Row::State::Invited) {
|
||||
if (const auto row = findRow(user)) {
|
||||
if (row->state() == Row::State::Invited
|
||||
|| row->state() == Row::State::Calling) {
|
||||
delegate()->peerListRemoveRow(row);
|
||||
delegate()->peerListRefreshRows();
|
||||
}
|
||||
}
|
||||
} else if (auto row = createInvitedRow(invite.user)) {
|
||||
} else if (auto row = createInvitedRow(user, invite.calling)) {
|
||||
delegate()->peerListAppendRow(std::move(row));
|
||||
delegate()->peerListRefreshRows();
|
||||
}
|
||||
|
@ -571,7 +575,8 @@ void Members::Controller::setupWithAccessUsers() {
|
|||
if (const auto count = delegate()->peerListFullRowsCount()) {
|
||||
const auto last = delegate()->peerListRowAt(count - 1);
|
||||
const auto state = static_cast<Row*>(last.get())->state();
|
||||
if (state == Row::State::Invited) {
|
||||
if (state == Row::State::Invited
|
||||
|| state == Row::State::Calling) {
|
||||
partition = true;
|
||||
}
|
||||
}
|
||||
|
@ -584,7 +589,8 @@ void Members::Controller::setupWithAccessUsers() {
|
|||
if (partition) {
|
||||
delegate()->peerListPartitionRows([](const PeerListRow &row) {
|
||||
const auto state = static_cast<const Row&>(row).state();
|
||||
return (state != Row::State::Invited);
|
||||
return (state != Row::State::Invited)
|
||||
&& (state != Row::State::Calling);
|
||||
});
|
||||
}
|
||||
delegate()->peerListRefreshRows();
|
||||
|
@ -599,6 +605,7 @@ void Members::Controller::updateRow(
|
|||
auto addedToBottom = (Row*)nullptr;
|
||||
if (const auto row = findRow(now.peer)) {
|
||||
if (row->state() == Row::State::Invited
|
||||
|| row->state() == Row::State::Calling
|
||||
|| row->state() == Row::State::WithAccess) {
|
||||
reorderIfNonRealBefore = row->absoluteIndex();
|
||||
}
|
||||
|
@ -631,7 +638,9 @@ void Members::Controller::updateRow(
|
|||
reorderIfNonRealBefore - 1).get();
|
||||
using State = Row::State;
|
||||
const auto state = static_cast<Row*>(row)->state();
|
||||
return (state == State::Invited) || (state == State::WithAccess);
|
||||
return (state == State::Invited)
|
||||
|| (state == State::Calling)
|
||||
|| (state == State::WithAccess);
|
||||
}();
|
||||
if (reorder) {
|
||||
partitionRows();
|
||||
|
@ -666,12 +675,15 @@ void Members::Controller::partitionRows() {
|
|||
if (state == State::WithAccess) {
|
||||
hadWithAccess = true;
|
||||
}
|
||||
return (state != State::Invited) && (state != State::WithAccess);
|
||||
return (state != State::Invited)
|
||||
&& (state != State::Calling)
|
||||
&& (state != State::WithAccess);
|
||||
});
|
||||
if (hadWithAccess) {
|
||||
delegate()->peerListPartitionRows([](const PeerListRow &row) {
|
||||
const auto state = static_cast<const Row&>(row).state();
|
||||
return (state != Row::State::Invited);
|
||||
return (state != Row::State::Invited)
|
||||
&& (state != Row::State::Calling);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -811,7 +823,7 @@ void Members::Controller::updateRow(
|
|||
} else if (noParticipantState == Row::State::WithAccess) {
|
||||
row->updateStateWithAccess();
|
||||
} else {
|
||||
row->updateStateInvited();
|
||||
row->updateStateInvited(noParticipantState == Row::State::Calling);
|
||||
}
|
||||
|
||||
const auto wasNoSounding = _soundingRowBySsrc.empty();
|
||||
|
@ -1093,15 +1105,21 @@ void Members::Controller::rowPaintIcon(
|
|||
return;
|
||||
}
|
||||
const auto narrow = (state.style == MembersRowStyle::Narrow);
|
||||
if (state.invited) {
|
||||
if (state.invited || state.calling) {
|
||||
if (narrow) {
|
||||
st::groupCallNarrowInvitedIcon.paintInCenter(p, rect);
|
||||
(state.invited
|
||||
? st::groupCallNarrowInvitedIcon
|
||||
: st::groupCallNarrowCallingIcon).paintInCenter(p, rect);
|
||||
} else {
|
||||
st::groupCallMemberInvited.paintInCenter(
|
||||
const auto &icon = state.invited
|
||||
? st::groupCallMemberInvited
|
||||
: st::groupCallMemberCalling;
|
||||
const auto shift = state.invited
|
||||
? st::groupCallMemberInvitedPosition
|
||||
: st::groupCallMemberCallingPosition;
|
||||
icon.paintInCenter(
|
||||
p,
|
||||
QRect(
|
||||
rect.topLeft() + st::groupCallMemberInvitedPosition,
|
||||
st::groupCallMemberInvited.size()));
|
||||
QRect(rect.topLeft() + shift, icon.size()));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -1464,9 +1482,10 @@ base::unique_qptr<Ui::PopupMenu> Members::Controller::createRowContextMenu(
|
|||
}
|
||||
} else {
|
||||
const auto conference = _call->conferenceCall().get();
|
||||
if (muteState == Row::State::Invited
|
||||
if (conference
|
||||
&& participantPeer->isUser()
|
||||
&& conference) {
|
||||
&& (muteState == Row::State::Invited
|
||||
|| muteState == Row::State::Calling)) {
|
||||
const auto id = conference->id();
|
||||
const auto cancelInvite = [=](bool discard) {
|
||||
Core::App().calls().declineOutgoingConferenceInvite(
|
||||
|
@ -1474,9 +1493,11 @@ base::unique_qptr<Ui::PopupMenu> Members::Controller::createRowContextMenu(
|
|||
participantPeer->asUser(),
|
||||
discard);
|
||||
};
|
||||
result->addAction(
|
||||
tr::lng_group_call_context_stop_ringing(tr::now),
|
||||
[=] { cancelInvite(false); });
|
||||
if (muteState == Row::State::Calling) {
|
||||
result->addAction(
|
||||
tr::lng_group_call_context_stop_ringing(tr::now),
|
||||
[=] { cancelInvite(false); });
|
||||
}
|
||||
result->addAction(
|
||||
tr::lng_group_call_context_cancel_invite(tr::now),
|
||||
[=] { cancelInvite(true); });
|
||||
|
@ -1497,6 +1518,7 @@ base::unique_qptr<Ui::PopupMenu> Members::Controller::createRowContextMenu(
|
|||
const auto canKick = [&] {
|
||||
const auto user = participantPeer->asUser();
|
||||
if (muteState == Row::State::Invited
|
||||
|| muteState == Row::State::Calling
|
||||
|| muteState == Row::State::WithAccess) {
|
||||
return false;
|
||||
} else if (const auto chat = _peer->asChat()) {
|
||||
|
@ -1626,6 +1648,7 @@ void Members::Controller::addMuteActionsToContextMenu(
|
|||
|
||||
const auto muteAction = [&]() -> QAction* {
|
||||
if (muteState == Row::State::Invited
|
||||
|| muteState == Row::State::Calling
|
||||
|| muteState == Row::State::WithAccess
|
||||
|| _call->rtmp()
|
||||
|| isMe(participantPeer)
|
||||
|
@ -1681,12 +1704,19 @@ std::unique_ptr<Row> Members::Controller::createRow(
|
|||
}
|
||||
|
||||
std::unique_ptr<Row> Members::Controller::createInvitedRow(
|
||||
not_null<PeerData*> participantPeer) {
|
||||
if (findRow(participantPeer)) {
|
||||
not_null<PeerData*> participantPeer,
|
||||
bool calling) {
|
||||
if (const auto row = findRow(participantPeer)) {
|
||||
if (row->state() == Row::State::Invited
|
||||
|| row->state() == Row::State::Calling) {
|
||||
row->updateStateInvited(calling);
|
||||
delegate()->peerListUpdateRow(row);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
const auto state = calling ? Row::State::Calling : Row::State::Invited;
|
||||
auto result = std::make_unique<Row>(this, participantPeer);
|
||||
updateRow(result.get(), std::nullopt, nullptr);
|
||||
updateRow(result.get(), std::nullopt, nullptr, state);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -138,9 +138,9 @@ void MembersRow::setSkipLevelUpdate(bool value) {
|
|||
_skipLevelUpdate = value;
|
||||
}
|
||||
|
||||
void MembersRow::updateStateInvited() {
|
||||
void MembersRow::updateStateInvited(bool calling) {
|
||||
setVolume(Group::kDefaultVolume);
|
||||
setState(State::Invited);
|
||||
setState(calling ? State::Calling : State::Invited);
|
||||
setSounding(false);
|
||||
setSpeaking(false);
|
||||
_mutedByMe = false;
|
||||
|
@ -640,11 +640,13 @@ void MembersRow::paintComplexStatusText(
|
|||
const auto useAbout = !_about.isEmpty()
|
||||
&& (_state != State::WithAccess)
|
||||
&& (_state != State::Invited)
|
||||
&& (_state != State::Calling)
|
||||
&& (style != MembersRowStyle::Video)
|
||||
&& ((_state == State::RaisedHand && !_raisedHandStatus)
|
||||
|| (_state != State::RaisedHand && !_speaking));
|
||||
if (!useAbout
|
||||
&& _state != State::Invited
|
||||
&& _state != State::Calling
|
||||
&& _state != State::WithAccess
|
||||
&& !_mutedByMe) {
|
||||
paintStatusIcon(p, x, y, st, font, selected, narrowMode);
|
||||
|
@ -693,6 +695,8 @@ void MembersRow::paintComplexStatusText(
|
|||
? tr::lng_status_connecting(tr::now)
|
||||
: (_state == State::WithAccess)
|
||||
? tr::lng_group_call_blockchain_only_status(tr::now)
|
||||
: (_state == State::Calling)
|
||||
? tr::lng_group_call_calling_status(tr::now)
|
||||
: tr::lng_group_call_invited_status(tr::now)));
|
||||
}
|
||||
}
|
||||
|
@ -706,6 +710,7 @@ QSize MembersRow::rightActionSize() const {
|
|||
bool MembersRow::rightActionDisabled() const {
|
||||
return _delegate->rowIsMe(peer())
|
||||
|| (_state == State::Invited)
|
||||
|| (_state == State::Calling)
|
||||
|| !_delegate->rowCanMuteMembers();
|
||||
}
|
||||
|
||||
|
@ -731,7 +736,9 @@ void MembersRow::rightActionPaint(
|
|||
size.width(),
|
||||
size.height(),
|
||||
outerWidth);
|
||||
if (_state == State::Invited) {
|
||||
if (_state == State::Invited
|
||||
|| _state == State::Calling
|
||||
|| _state == State::WithAccess) {
|
||||
_actionRipple = nullptr;
|
||||
}
|
||||
if (_actionRipple) {
|
||||
|
@ -761,6 +768,7 @@ MembersRowDelegate::IconState MembersRow::computeIconState(
|
|||
.mutedByMe = _mutedByMe,
|
||||
.raisedHand = (_state == State::RaisedHand),
|
||||
.invited = (_state == State::Invited),
|
||||
.calling = (_state == State::Calling),
|
||||
.style = style,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ struct PeerUserpicView;
|
|||
|
||||
namespace Calls::Group {
|
||||
|
||||
enum class MembersRowStyle {
|
||||
enum class MembersRowStyle : uchar {
|
||||
Default,
|
||||
Narrow,
|
||||
Video,
|
||||
|
@ -40,6 +40,7 @@ public:
|
|||
bool mutedByMe = false;
|
||||
bool raisedHand = false;
|
||||
bool invited = false;
|
||||
bool calling = false;
|
||||
MembersRowStyle style = MembersRowStyle::Default;
|
||||
};
|
||||
virtual bool rowIsMe(not_null<PeerData*> participantPeer) = 0;
|
||||
|
@ -75,13 +76,14 @@ public:
|
|||
Muted,
|
||||
RaisedHand,
|
||||
Invited,
|
||||
Calling,
|
||||
WithAccess,
|
||||
};
|
||||
|
||||
void setAbout(const QString &about);
|
||||
void setSkipLevelUpdate(bool value);
|
||||
void updateState(const Data::GroupCallParticipant &participant);
|
||||
void updateStateInvited();
|
||||
void updateStateInvited(bool calling);
|
||||
void updateStateWithAccess();
|
||||
void updateLevel(float level);
|
||||
void updateBlobAnimation(crl::time now);
|
||||
|
|
|
@ -791,7 +791,10 @@ void GroupCall::applyParticipantsSlice(
|
|||
}
|
||||
if (adding) {
|
||||
if (const auto user = participantPeer->asUser()) {
|
||||
_peer->owner().unregisterInvitedToCallUser(_id, user);
|
||||
_peer->owner().unregisterInvitedToCallUser(
|
||||
_id,
|
||||
user,
|
||||
false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1701,13 +1701,11 @@ MediaCall::MediaCall(not_null<HistoryItem*> parent, const Call &call)
|
|||
const auto peer = parent->history()->peer;
|
||||
peer->owner().registerCallItem(parent);
|
||||
if (const auto user = _call.conferenceId ? peer->asUser() : nullptr) {
|
||||
if (_call.state == CallState::Invitation) {
|
||||
Core::App().calls().registerConferenceInvite(
|
||||
_call.conferenceId,
|
||||
user,
|
||||
parent->id,
|
||||
!parent->out());
|
||||
}
|
||||
Core::App().calls().registerConferenceInvite(
|
||||
_call.conferenceId,
|
||||
user,
|
||||
parent->id,
|
||||
!parent->out());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1716,13 +1714,11 @@ MediaCall::~MediaCall() {
|
|||
const auto peer = parent->history()->peer;
|
||||
peer->owner().unregisterCallItem(parent);
|
||||
if (const auto user = _call.conferenceId ? peer->asUser() : nullptr) {
|
||||
if (_call.state == CallState::Invitation) {
|
||||
Core::App().calls().unregisterConferenceInvite(
|
||||
_call.conferenceId,
|
||||
user,
|
||||
parent->id,
|
||||
!parent->out());
|
||||
}
|
||||
Core::App().calls().unregisterConferenceInvite(
|
||||
_call.conferenceId,
|
||||
user,
|
||||
parent->id,
|
||||
!parent->out());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1219,8 +1219,8 @@ void Session::checkLocalUsersWentOffline() {
|
|||
}
|
||||
|
||||
auto Session::invitedToCallUsers(CallId callId) const
|
||||
-> const base::flat_set<not_null<UserData*>> & {
|
||||
static const base::flat_set<not_null<UserData*>> kEmpty;
|
||||
-> const base::flat_map<not_null<UserData*>, bool> & {
|
||||
static const base::flat_map<not_null<UserData*>, bool> kEmpty;
|
||||
const auto i = _invitedToCallUsers.find(callId);
|
||||
return (i != _invitedToCallUsers.end()) ? i->second : kEmpty;
|
||||
}
|
||||
|
@ -1228,14 +1228,16 @@ auto Session::invitedToCallUsers(CallId callId) const
|
|||
void Session::registerInvitedToCallUser(
|
||||
CallId callId,
|
||||
not_null<PeerData*> peer,
|
||||
not_null<UserData*> user) {
|
||||
registerInvitedToCallUser(callId, peer->groupCall(), user);
|
||||
not_null<UserData*> user,
|
||||
bool calling) {
|
||||
registerInvitedToCallUser(callId, peer->groupCall(), user, calling);
|
||||
}
|
||||
|
||||
void Session::registerInvitedToCallUser(
|
||||
CallId callId,
|
||||
GroupCall *call,
|
||||
not_null<UserData*> user) {
|
||||
not_null<UserData*> user,
|
||||
bool calling) {
|
||||
if (call && call->id() == callId) {
|
||||
const auto inCall = ranges::contains(
|
||||
call->participants(),
|
||||
|
@ -1245,19 +1247,32 @@ void Session::registerInvitedToCallUser(
|
|||
return;
|
||||
}
|
||||
}
|
||||
_invitedToCallUsers[callId].emplace(user);
|
||||
_invitesToCalls.fire({ callId, user });
|
||||
_invitedToCallUsers[callId][user] = calling;
|
||||
_invitesToCalls.fire({ callId, user, calling });
|
||||
}
|
||||
|
||||
void Session::unregisterInvitedToCallUser(
|
||||
CallId callId,
|
||||
not_null<UserData*> user) {
|
||||
not_null<UserData*> user,
|
||||
bool onlyStopCalling) {
|
||||
const auto i = _invitedToCallUsers.find(callId);
|
||||
if (i != _invitedToCallUsers.end()) {
|
||||
i->second.remove(user);
|
||||
if (i->second.empty()) {
|
||||
_invitedToCallUsers.erase(i);
|
||||
_invitesToCalls.fire({ callId, user, true });
|
||||
const auto j = i->second.find(user);
|
||||
if (j != end(i->second)) {
|
||||
if (onlyStopCalling) {
|
||||
if (!j->second) {
|
||||
return;
|
||||
}
|
||||
j->second = false;
|
||||
} else {
|
||||
i->second.erase(j);
|
||||
if (i->second.empty()) {
|
||||
_invitedToCallUsers.erase(i);
|
||||
}
|
||||
}
|
||||
const auto calling = false;
|
||||
const auto removed = !onlyStopCalling;
|
||||
_invitesToCalls.fire({ callId, user, calling, removed });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -240,22 +240,26 @@ public:
|
|||
void maybeStopWatchForOffline(not_null<UserData*> user);
|
||||
|
||||
[[nodiscard]] auto invitedToCallUsers(CallId callId) const
|
||||
-> const base::flat_set<not_null<UserData*>> &;
|
||||
-> const base::flat_map<not_null<UserData*>, bool> &;
|
||||
void registerInvitedToCallUser(
|
||||
CallId callId,
|
||||
not_null<PeerData*> peer,
|
||||
not_null<UserData*> user);
|
||||
not_null<UserData*> user,
|
||||
bool calling);
|
||||
void registerInvitedToCallUser(
|
||||
CallId callId,
|
||||
GroupCall *call,
|
||||
not_null<UserData*> user);
|
||||
not_null<UserData*> user,
|
||||
bool calling);
|
||||
void unregisterInvitedToCallUser(
|
||||
CallId callId,
|
||||
not_null<UserData*> user);
|
||||
not_null<UserData*> user,
|
||||
bool onlyStopCalling);
|
||||
|
||||
struct InviteToCall {
|
||||
CallId id = 0;
|
||||
not_null<UserData*> user;
|
||||
bool calling = false;
|
||||
bool removed = false;
|
||||
};
|
||||
[[nodiscard]] rpl::producer<InviteToCall> invitesToCalls() const {
|
||||
|
@ -1112,7 +1116,7 @@ private:
|
|||
rpl::event_stream<InviteToCall> _invitesToCalls;
|
||||
base::flat_map<
|
||||
CallId,
|
||||
base::flat_set<not_null<UserData*>>> _invitedToCallUsers;
|
||||
base::flat_map<not_null<UserData*>, bool>> _invitedToCallUsers;
|
||||
|
||||
base::flat_set<not_null<ViewElement*>> _shownSpoilers;
|
||||
base::flat_map<
|
||||
|
|
|
@ -1902,12 +1902,21 @@ void HistoryItem::applyEdition(const MTPDmessageService &message) {
|
|||
_flags &= ~MessageFlag::DisplayFromChecked;
|
||||
} else if (message.vaction().type() == mtpc_messageActionConferenceCall) {
|
||||
removeFromSharedMediaIndex();
|
||||
const auto owner = &history()->owner();
|
||||
const auto &data = message.vaction().c_messageActionConferenceCall();
|
||||
const auto info = Data::ComputeCallData(owner, data);
|
||||
if (const auto user = history()->peer->asUser()) {
|
||||
if (const auto conferenceId = out() ? info.conferenceId : 0) {
|
||||
Core::App().calls().unregisterConferenceInvite(
|
||||
conferenceId,
|
||||
user,
|
||||
id,
|
||||
!out(),
|
||||
true);
|
||||
}
|
||||
}
|
||||
_media = nullptr;
|
||||
_media = std::make_unique<Data::MediaCall>(
|
||||
this,
|
||||
Data::ComputeCallData(
|
||||
&history()->owner(),
|
||||
message.vaction().c_messageActionConferenceCall()));
|
||||
_media = std::make_unique<Data::MediaCall>(this, info);
|
||||
addToSharedMediaIndex();
|
||||
finishEdition(-1);
|
||||
_flags &= ~MessageFlag::DisplayFromChecked;
|
||||
|
@ -4896,7 +4905,7 @@ void HistoryItem::setServiceMessageByAction(const MTPmessageAction &action) {
|
|||
for (const auto &id : action.vusers().v) {
|
||||
const auto user = owner->user(id.v);
|
||||
if (callId) {
|
||||
owner->registerInvitedToCallUser(callId, peer, user);
|
||||
owner->registerInvitedToCallUser(callId, peer, user, false);
|
||||
}
|
||||
};
|
||||
const auto linkCallId = PeerHasThisCall(peer, callId).value_or(false)
|
||||
|
|
Loading…
Add table
Reference in a new issue