mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-15 21:57:10 +02:00
Switch between videos by left click.
This commit is contained in:
parent
7e8d1f7974
commit
3a321d64f6
5 changed files with 173 additions and 134 deletions
|
@ -47,6 +47,7 @@ constexpr auto kCheckLastSpokeInterval = crl::time(1000);
|
|||
constexpr auto kCheckJoinedTimeout = 4 * crl::time(1000);
|
||||
constexpr auto kUpdateSendActionEach = crl::time(500);
|
||||
constexpr auto kPlayConnectingEach = crl::time(1056) + 2 * crl::time(1000);
|
||||
constexpr auto kFixLargeVideoDuration = 5 * crl::time(1000);
|
||||
|
||||
[[nodiscard]] std::unique_ptr<Webrtc::MediaDevices> CreateMediaDevices() {
|
||||
const auto &settings = Core::App().settings();
|
||||
|
@ -61,15 +62,9 @@ constexpr auto kPlayConnectingEach = crl::time(1056) + 2 * crl::time(1000);
|
|||
uint64 id,
|
||||
not_null<PeerData*> participantPeer) {
|
||||
const auto call = peer->groupCall();
|
||||
if (!id || !call || call->id() != id) {
|
||||
return nullptr;
|
||||
}
|
||||
const auto &participants = call->participants();
|
||||
const auto i = ranges::find(
|
||||
participants,
|
||||
participantPeer,
|
||||
&Data::GroupCallParticipant::peer);
|
||||
return (i != end(participants)) ? &*i : nullptr;
|
||||
return (id && call && call->id() == id)
|
||||
? call->participantByPeer(participantPeer)
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
[[nodiscard]] double TimestampFromMsgId(mtpMsgId msgId) {
|
||||
|
@ -559,7 +554,7 @@ void GroupCall::subscribeToReal(not_null<Data::GroupCall*> real) {
|
|||
newLarge = chooseLargeVideoEndpoint();
|
||||
}
|
||||
if (_videoEndpointLarge.current() != newLarge) {
|
||||
_videoEndpointLarge = newLarge;
|
||||
setVideoEndpointLarge(newLarge);
|
||||
}
|
||||
if (!updateCameraNotStreams.empty()) {
|
||||
_streamsVideoUpdated.fire({ updateCameraNotStreams, false });
|
||||
|
@ -624,7 +619,10 @@ void GroupCall::subscribeToReal(not_null<Data::GroupCall*> real) {
|
|||
const auto wasSounding = data.was && data.was->sounding;
|
||||
if (nowSpeaking == wasSpeaking && nowSounding == wasSounding) {
|
||||
return;
|
||||
} else if (_videoEndpointPinned.current()) {
|
||||
} else if (_videoEndpointPinned.current()
|
||||
|| (_videoLargeShowTime
|
||||
&& _videoLargeShowTime + kFixLargeVideoDuration
|
||||
> crl::now())) {
|
||||
return;
|
||||
}
|
||||
if (nowScreenEndpoint != newLarge.endpoint
|
||||
|
@ -880,7 +878,7 @@ void GroupCall::setMyEndpointType(
|
|||
auto newLarge = _videoEndpointLarge.current();
|
||||
if (newLarge.endpoint == endpoint) {
|
||||
_videoEndpointPinned = false;
|
||||
_videoEndpointLarge = chooseLargeVideoEndpoint();
|
||||
setVideoEndpointLarge(chooseLargeVideoEndpoint());
|
||||
}
|
||||
_streamsVideoUpdated.fire({ endpoint, false });
|
||||
}
|
||||
|
@ -899,7 +897,7 @@ void GroupCall::setMyEndpointType(
|
|||
&& nowLarge != EndpointType::Screen)
|
||||
|| (type == EndpointType::Camera
|
||||
&& nowLarge == EndpointType::None))) {
|
||||
_videoEndpointLarge = VideoEndpoint{ _joinAs, endpoint };
|
||||
setVideoEndpointLarge(VideoEndpoint{ _joinAs, endpoint });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1132,34 +1130,30 @@ void GroupCall::leavePresentation() {
|
|||
}
|
||||
|
||||
void GroupCall::applyMeInCallLocally() {
|
||||
const auto call = _peer->groupCall();
|
||||
if (!call || call->id() != _id) {
|
||||
const auto real = lookupReal();
|
||||
if (!real) {
|
||||
return;
|
||||
}
|
||||
using Flag = MTPDgroupCallParticipant::Flag;
|
||||
const auto &participants = call->participants();
|
||||
const auto i = ranges::find(
|
||||
participants,
|
||||
_joinAs,
|
||||
&Data::GroupCallParticipant::peer);
|
||||
const auto date = (i != end(participants))
|
||||
? i->date
|
||||
const auto participant = real->participantByPeer(_joinAs);
|
||||
const auto date = participant
|
||||
? participant->date
|
||||
: base::unixtime::now();
|
||||
const auto lastActive = (i != end(participants))
|
||||
? i->lastActive
|
||||
const auto lastActive = participant
|
||||
? participant->lastActive
|
||||
: TimeId(0);
|
||||
const auto volume = (i != end(participants))
|
||||
? i->volume
|
||||
const auto volume = participant
|
||||
? participant->volume
|
||||
: Group::kDefaultVolume;
|
||||
const auto canSelfUnmute = (muted() != MuteState::ForceMuted)
|
||||
&& (muted() != MuteState::RaisedHand);
|
||||
const auto raisedHandRating = (muted() != MuteState::RaisedHand)
|
||||
? uint64(0)
|
||||
: (i != end(participants))
|
||||
? i->raisedHandRating
|
||||
: FindLocalRaisedHandRating(participants);
|
||||
const auto params = (i != end(participants))
|
||||
? i->videoParams.get()
|
||||
: participant
|
||||
? participant->raisedHandRating
|
||||
: FindLocalRaisedHandRating(real->participants());
|
||||
const auto params = participant
|
||||
? participant->videoParams.get()
|
||||
: nullptr;
|
||||
const auto flags = (canSelfUnmute ? Flag::f_can_self_unmute : Flag(0))
|
||||
| (lastActive ? Flag::f_active_date : Flag(0))
|
||||
|
@ -1173,7 +1167,7 @@ void GroupCall::applyMeInCallLocally() {
|
|||
? Flag::f_presentation
|
||||
: Flag(0))
|
||||
| (raisedHandRating > 0 ? Flag::f_raise_hand_rating : Flag(0));
|
||||
call->applyLocalUpdate(
|
||||
real->applyLocalUpdate(
|
||||
MTP_updateGroupCallParticipants(
|
||||
inputCall(),
|
||||
MTP_vector<MTPGroupCallParticipant>(
|
||||
|
@ -2013,17 +2007,15 @@ bool GroupCall::mediaChannelDescriptionsFill(
|
|||
const auto addVideoChannel = [&](
|
||||
not_null<PeerData*> participantPeer,
|
||||
const auto field) {
|
||||
const auto i = ranges::find(
|
||||
existing,
|
||||
participantPeer,
|
||||
&Data::GroupCallParticipant::peer);
|
||||
Assert(i != end(existing));
|
||||
Assert(i->videoParams != nullptr);
|
||||
const auto ¶ms = i->videoParams.get()->*field;
|
||||
const auto participant = real->participantByPeer(
|
||||
participantPeer);
|
||||
Assert(participant != nullptr);
|
||||
Assert(participant->videoParams != nullptr);
|
||||
const auto ¶ms = participant->videoParams.get()->*field;
|
||||
Assert(!params.empty());
|
||||
add(Channel{
|
||||
.type = Channel::Type::Video,
|
||||
.audioSsrc = i->ssrc,
|
||||
.audioSsrc = participant->ssrc,
|
||||
.videoInformation = params.json.toStdString(),
|
||||
}, (field == &ParticipantVideoParams::screen));
|
||||
};
|
||||
|
@ -2085,7 +2077,7 @@ void GroupCall::setIncomingVideoEndpoints(
|
|||
newLarge = VideoEndpoint();
|
||||
}
|
||||
if (newLarge.empty()) {
|
||||
_videoEndpointLarge = chooseLargeVideoEndpoint();
|
||||
setVideoEndpointLarge(chooseLargeVideoEndpoint());
|
||||
}
|
||||
for (const auto &endpoint : removed) {
|
||||
if (_activeVideoEndpoints.contains(endpoint)) {
|
||||
|
@ -2134,7 +2126,7 @@ void GroupCall::fillActiveVideoEndpoints() {
|
|||
newLarge = VideoEndpoint();
|
||||
}
|
||||
if (!newLarge) {
|
||||
_videoEndpointLarge = chooseLargeVideoEndpoint();
|
||||
setVideoEndpointLarge(chooseLargeVideoEndpoint());
|
||||
}
|
||||
for (const auto &[endpoint, type] : removed) {
|
||||
if (_activeVideoEndpoints.remove(endpoint)) {
|
||||
|
@ -2494,16 +2486,30 @@ void GroupCall::sendSelfUpdate(SendUpdateType type) {
|
|||
}).send();
|
||||
}
|
||||
|
||||
void GroupCall::pinVideoEndpoint(const VideoEndpoint &endpoint) {
|
||||
void GroupCall::pinVideoEndpoint(VideoEndpoint endpoint) {
|
||||
if (!endpoint) {
|
||||
_videoEndpointPinned = false;
|
||||
} else if (streamsVideo(endpoint.endpoint)) {
|
||||
_videoEndpointPinned = false;
|
||||
_videoEndpointLarge = endpoint;
|
||||
setVideoEndpointLarge(std::move(endpoint));
|
||||
_videoEndpointPinned = true;
|
||||
}
|
||||
}
|
||||
|
||||
void GroupCall::showVideoEndpointLarge(VideoEndpoint endpoint) {
|
||||
if (!streamsVideo(endpoint.endpoint)) {
|
||||
return;
|
||||
}
|
||||
_videoEndpointPinned = false;
|
||||
setVideoEndpointLarge(std::move(endpoint));
|
||||
_videoLargeShowTime = crl::now();
|
||||
}
|
||||
|
||||
void GroupCall::setVideoEndpointLarge(VideoEndpoint endpoint) {
|
||||
_videoEndpointLarge = endpoint;
|
||||
_videoLargeShowTime = 0;
|
||||
}
|
||||
|
||||
void GroupCall::setCurrentAudioDevice(bool input, const QString &deviceId) {
|
||||
if (input) {
|
||||
_mediaDevices->switchToAudioInput(deviceId);
|
||||
|
@ -2572,13 +2578,9 @@ std::variant<int, not_null<UserData*>> GroupCall::inviteUsers(
|
|||
}
|
||||
const auto owner = &_peer->owner();
|
||||
const auto &invited = owner->invitedToCallUsers(_id);
|
||||
const auto &participants = real->participants();
|
||||
auto &&toInvite = users | ranges::views::filter([&](
|
||||
not_null<UserData*> user) {
|
||||
return !invited.contains(user) && !ranges::contains(
|
||||
participants,
|
||||
user,
|
||||
&Data::GroupCallParticipant::peer);
|
||||
return !invited.contains(user) && !real->participantByPeer(user);
|
||||
});
|
||||
|
||||
auto count = 0;
|
||||
|
|
|
@ -289,7 +289,7 @@ public:
|
|||
[[nodiscard]] rpl::producer<bool> videoEndpointPinnedValue() const {
|
||||
return _videoEndpointPinned.value();
|
||||
}
|
||||
void pinVideoEndpoint(const VideoEndpoint &endpoint);
|
||||
void pinVideoEndpoint(VideoEndpoint endpoint);
|
||||
[[nodiscard]] const VideoEndpoint &videoEndpointLarge() const {
|
||||
return _videoEndpointLarge.current();
|
||||
}
|
||||
|
@ -297,6 +297,7 @@ public:
|
|||
-> rpl::producer<VideoEndpoint> {
|
||||
return _videoEndpointLarge.value();
|
||||
}
|
||||
void showVideoEndpointLarge(VideoEndpoint endpoint);
|
||||
struct LargeTrack {
|
||||
Webrtc::VideoTrack *track = nullptr;
|
||||
PeerData *peer = nullptr;
|
||||
|
@ -451,6 +452,7 @@ private:
|
|||
[[nodiscard]] VideoEndpoint chooseLargeVideoEndpoint() const;
|
||||
[[nodiscard]] EndpointType activeVideoEndpointType(
|
||||
const std::string &endpoint) const;
|
||||
void setVideoEndpointLarge(VideoEndpoint endpoint);
|
||||
|
||||
void editParticipant(
|
||||
not_null<PeerData*> participantPeer,
|
||||
|
@ -539,6 +541,7 @@ private:
|
|||
rpl::variable<bool> _videoEndpointPinned;
|
||||
std::unique_ptr<Webrtc::VideoTrack> _videoLargeTrackWrap;
|
||||
rpl::variable<LargeTrack> _videoLargeTrack;
|
||||
crl::time _videoLargeShowTime = 0;
|
||||
base::flat_map<uint32, Data::LastSpokeTimes> _lastSpoke;
|
||||
rpl::event_stream<Group::RejoinEvent> _rejoinEvents;
|
||||
rpl::event_stream<> _allowedToSpeakNotifications;
|
||||
|
|
|
@ -159,6 +159,8 @@ private:
|
|||
void setRowVideoEndpoint(
|
||||
not_null<Row*> row,
|
||||
const std::string &endpoint);
|
||||
bool toggleRowVideo(not_null<PeerListRow*> row);
|
||||
void showRowMenu(not_null<PeerListRow*> row);
|
||||
|
||||
void generateNarrowShadow();
|
||||
void appendInvitedUsers();
|
||||
|
@ -377,16 +379,13 @@ void Members::Controller::setupListChangeViewers() {
|
|||
const auto row = i->second;
|
||||
const auto real = _call->lookupReal();
|
||||
Assert(real != nullptr);
|
||||
const auto &participants = real->participants();
|
||||
const auto j = ranges::find(
|
||||
participants,
|
||||
row->peer(),
|
||||
&Data::GroupCallParticipant::peer);
|
||||
if (j == end(participants)) {
|
||||
const auto participant = real->participantByPeer(
|
||||
row->peer());
|
||||
if (!participant) {
|
||||
setRowVideoEndpoint(row, std::string());
|
||||
} else {
|
||||
const auto &camera = computeCameraEndpoint(&*j);
|
||||
const auto &screen = computeScreenEndpoint(&*j);
|
||||
const auto &camera = computeCameraEndpoint(participant);
|
||||
const auto &screen = computeScreenEndpoint(participant);
|
||||
if (update.endpoint == camera
|
||||
&& (_largeEndpoint != screen)
|
||||
&& _call->streamsVideo(screen)) {
|
||||
|
@ -730,12 +729,7 @@ const Data::GroupCallParticipant *Members::Controller::findParticipant(
|
|||
return nullptr;
|
||||
} else if (endpoint == _call->screenSharingEndpoint()
|
||||
|| endpoint == _call->cameraSharingEndpoint()) {
|
||||
const auto &participants = real->participants();
|
||||
const auto i = ranges::find(
|
||||
participants,
|
||||
_call->joinAs(),
|
||||
&Data::GroupCallParticipant::peer);
|
||||
return (i != end(participants)) ? &*i : nullptr;
|
||||
return real->participantByPeer(_call->joinAs());
|
||||
} else {
|
||||
return real->participantByEndpoint(endpoint);
|
||||
}
|
||||
|
@ -784,7 +778,6 @@ bool Members::Controller::isMe(not_null<PeerData*> participantPeer) const {
|
|||
void Members::Controller::prepareRows(not_null<Data::GroupCall*> real) {
|
||||
auto foundMe = false;
|
||||
auto changed = false;
|
||||
const auto &participants = real->participants();
|
||||
auto count = delegate()->peerListFullRowsCount();
|
||||
for (auto i = 0; i != count;) {
|
||||
auto row = delegate()->peerListRowAt(i);
|
||||
|
@ -794,11 +787,7 @@ void Members::Controller::prepareRows(not_null<Data::GroupCall*> real) {
|
|||
++i;
|
||||
continue;
|
||||
}
|
||||
const auto contains = ranges::contains(
|
||||
participants,
|
||||
participantPeer,
|
||||
&Data::GroupCallParticipant::peer);
|
||||
if (contains) {
|
||||
if (real->participantByPeer(participantPeer)) {
|
||||
++i;
|
||||
} else {
|
||||
changed = true;
|
||||
|
@ -808,19 +797,16 @@ void Members::Controller::prepareRows(not_null<Data::GroupCall*> real) {
|
|||
}
|
||||
if (!foundMe) {
|
||||
const auto me = _call->joinAs();
|
||||
const auto i = ranges::find(
|
||||
participants,
|
||||
me,
|
||||
&Data::GroupCallParticipant::peer);
|
||||
auto row = (i != end(participants))
|
||||
? createRow(*i)
|
||||
const auto participant = real->participantByPeer(me);
|
||||
auto row = participant
|
||||
? createRow(*participant)
|
||||
: createRowForMe();
|
||||
if (row) {
|
||||
changed = true;
|
||||
delegate()->peerListAppendRow(std::move(row));
|
||||
}
|
||||
}
|
||||
for (const auto &participant : participants) {
|
||||
for (const auto &participant : real->participants()) {
|
||||
if (auto row = createRow(participant)) {
|
||||
changed = true;
|
||||
delegate()->peerListAppendRow(std::move(row));
|
||||
|
@ -1089,6 +1075,12 @@ auto Members::Controller::kickParticipantRequests() const
|
|||
}
|
||||
|
||||
void Members::Controller::rowClicked(not_null<PeerListRow*> row) {
|
||||
if (!toggleRowVideo(row)) {
|
||||
showRowMenu(row);
|
||||
}
|
||||
}
|
||||
|
||||
void Members::Controller::showRowMenu(not_null<PeerListRow*> row) {
|
||||
delegate()->peerListShowRowMenu(row, [=](not_null<Ui::PopupMenu*> menu) {
|
||||
if (!_menu || _menu.get() != menu) {
|
||||
return;
|
||||
|
@ -1103,9 +1095,51 @@ void Members::Controller::rowClicked(not_null<PeerListRow*> row) {
|
|||
});
|
||||
}
|
||||
|
||||
bool Members::Controller::toggleRowVideo(not_null<PeerListRow*> row) {
|
||||
const auto real = _call->lookupReal();
|
||||
if (!real) {
|
||||
return false;
|
||||
}
|
||||
const auto participantPeer = row->peer();
|
||||
const auto isMe = (participantPeer == _call->joinAs());
|
||||
const auto participant = real->participantByPeer(participantPeer);
|
||||
if (!participant) {
|
||||
return false;
|
||||
}
|
||||
const auto params = participant->videoParams.get();
|
||||
const auto empty = std::string();
|
||||
const auto &camera = isMe
|
||||
? _call->cameraSharingEndpoint()
|
||||
: (params && _call->streamsVideo(params->camera.endpoint))
|
||||
? params->camera.endpoint
|
||||
: empty;
|
||||
const auto &screen = isMe
|
||||
? _call->screenSharingEndpoint()
|
||||
: (params && _call->streamsVideo(params->screen.endpoint))
|
||||
? params->screen.endpoint
|
||||
: empty;
|
||||
const auto &large = _call->videoEndpointLarge().endpoint;
|
||||
const auto show = [&] {
|
||||
if (!screen.empty() && large != screen) {
|
||||
return screen;
|
||||
} else if (!camera.empty() && large != camera) {
|
||||
return camera;
|
||||
}
|
||||
return std::string();
|
||||
}();
|
||||
if (show.empty()) {
|
||||
return false;
|
||||
} else if (_call->videoEndpointPinned()) {
|
||||
_call->pinVideoEndpoint({ participantPeer, show });
|
||||
} else {
|
||||
_call->showVideoEndpointLarge({ participantPeer, show });
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void Members::Controller::rowActionClicked(
|
||||
not_null<PeerListRow*> row) {
|
||||
rowClicked(row);
|
||||
showRowMenu(row);
|
||||
}
|
||||
|
||||
base::unique_qptr<Ui::PopupMenu> Members::Controller::rowContextMenu(
|
||||
|
@ -1195,26 +1229,20 @@ base::unique_qptr<Ui::PopupMenu> Members::Controller::createRowContextMenu(
|
|||
result->addAction(
|
||||
tr::lng_group_call_context_unpin_camera(tr::now),
|
||||
[=] { _call->pinVideoEndpoint(VideoEndpoint()); });
|
||||
} else {
|
||||
const auto &participants = real->participants();
|
||||
const auto i = ranges::find(
|
||||
participants,
|
||||
participantPeer,
|
||||
&Data::GroupCallParticipant::peer);
|
||||
if (i != end(participants)) {
|
||||
const auto &camera = computeCameraEndpoint(&*i);
|
||||
const auto &screen = computeScreenEndpoint(&*i);
|
||||
const auto streamsScreen = _call->streamsVideo(screen);
|
||||
if (streamsScreen || _call->streamsVideo(camera)) {
|
||||
const auto callback = [=] {
|
||||
_call->pinVideoEndpoint(VideoEndpoint{
|
||||
participantPeer,
|
||||
streamsScreen ? screen : camera });
|
||||
};
|
||||
result->addAction(
|
||||
tr::lng_group_call_context_pin_camera(tr::now),
|
||||
callback);
|
||||
}
|
||||
} else if (const auto participant = real->participantByPeer(
|
||||
participantPeer)) {
|
||||
const auto &camera = computeCameraEndpoint(participant);
|
||||
const auto &screen = computeScreenEndpoint(participant);
|
||||
const auto streamsScreen = _call->streamsVideo(screen);
|
||||
if (streamsScreen || _call->streamsVideo(camera)) {
|
||||
const auto callback = [=] {
|
||||
_call->pinVideoEndpoint(VideoEndpoint{
|
||||
participantPeer,
|
||||
streamsScreen ? screen : camera });
|
||||
};
|
||||
result->addAction(
|
||||
tr::lng_group_call_context_pin_camera(tr::now),
|
||||
callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -229,6 +229,17 @@ PeerData *GroupCall::participantPeerByScreenSsrc(uint32 ssrc) const {
|
|||
: nullptr;
|
||||
}
|
||||
|
||||
const GroupCallParticipant *GroupCall::participantByPeer(
|
||||
not_null<PeerData*> peer) const {
|
||||
return const_cast<GroupCall*>(this)->findParticipant(peer);
|
||||
}
|
||||
|
||||
GroupCallParticipant *GroupCall::findParticipant(
|
||||
not_null<PeerData*> peer) {
|
||||
const auto i = ranges::find(_participants, peer, &Participant::peer);
|
||||
return (i != end(_participants)) ? &*i : nullptr;
|
||||
}
|
||||
|
||||
const GroupCallParticipant *GroupCall::participantByEndpoint(
|
||||
const std::string &endpoint) const {
|
||||
if (endpoint.empty()) {
|
||||
|
@ -683,24 +694,22 @@ void GroupCall::applyLastSpoke(
|
|||
requestUnknownParticipants();
|
||||
return;
|
||||
}
|
||||
const auto j = ranges::find(
|
||||
_participants,
|
||||
i->second,
|
||||
&Participant::peer);
|
||||
Assert(j != end(_participants));
|
||||
const auto participant = findParticipant(i->second);
|
||||
Assert(participant != nullptr);
|
||||
|
||||
_speakingByActiveFinishes.remove(j->peer);
|
||||
_speakingByActiveFinishes.remove(participant->peer);
|
||||
const auto sounding = (when.anything + kSoundStatusKeptFor >= now)
|
||||
&& j->canSelfUnmute;
|
||||
&& participant->canSelfUnmute;
|
||||
const auto speaking = sounding
|
||||
&& (when.voice + kSoundStatusKeptFor >= now);
|
||||
if (j->sounding != sounding || j->speaking != speaking) {
|
||||
const auto was = *j;
|
||||
j->sounding = sounding;
|
||||
j->speaking = speaking;
|
||||
if (participant->sounding != sounding
|
||||
|| participant->speaking != speaking) {
|
||||
const auto was = *participant;
|
||||
participant->sounding = sounding;
|
||||
participant->speaking = speaking;
|
||||
_participantUpdates.fire({
|
||||
.was = was,
|
||||
.now = *j,
|
||||
.now = *participant,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -722,41 +731,37 @@ void GroupCall::applyActiveUpdate(
|
|||
if (inCall()) {
|
||||
return;
|
||||
}
|
||||
const auto i = participantPeerLoaded
|
||||
? ranges::find(
|
||||
_participants,
|
||||
not_null{ participantPeerLoaded },
|
||||
&Participant::peer)
|
||||
: _participants.end();
|
||||
const auto notFound = (i == end(_participants));
|
||||
const auto loadByUserId = notFound || i->onlyMinLoaded;
|
||||
const auto participant = participantPeerLoaded
|
||||
? findParticipant(participantPeerLoaded)
|
||||
: nullptr;
|
||||
const auto loadByUserId = !participant || participant->onlyMinLoaded;
|
||||
if (loadByUserId) {
|
||||
_unknownSpokenPeerIds[participantPeerId] = when;
|
||||
requestUnknownParticipants();
|
||||
}
|
||||
if (notFound || !i->canSelfUnmute) {
|
||||
if (!participant || !participant->canSelfUnmute) {
|
||||
return;
|
||||
}
|
||||
const auto was = std::make_optional(*i);
|
||||
const auto was = std::make_optional(*participant);
|
||||
const auto now = crl::now();
|
||||
const auto elapsed = TimeId((now - when.anything) / crl::time(1000));
|
||||
const auto lastActive = base::unixtime::now() - elapsed;
|
||||
const auto finishes = when.anything + kSpeakingAfterActive;
|
||||
if (lastActive <= i->lastActive || finishes <= now) {
|
||||
if (lastActive <= participant->lastActive || finishes <= now) {
|
||||
return;
|
||||
}
|
||||
_speakingByActiveFinishes[i->peer] = finishes;
|
||||
_speakingByActiveFinishes[participant->peer] = finishes;
|
||||
if (!_speakingByActiveFinishTimer.isActive()) {
|
||||
_speakingByActiveFinishTimer.callOnce(finishes - now);
|
||||
}
|
||||
|
||||
i->lastActive = lastActive;
|
||||
i->speaking = true;
|
||||
i->canSelfUnmute = true;
|
||||
participant->lastActive = lastActive;
|
||||
participant->speaking = true;
|
||||
participant->canSelfUnmute = true;
|
||||
if (!was->speaking || !was->canSelfUnmute) {
|
||||
_participantUpdates.fire({
|
||||
.was = was,
|
||||
.now = *i,
|
||||
.now = *participant,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -779,16 +784,14 @@ void GroupCall::checkFinishSpeakingByActive() {
|
|||
}
|
||||
}
|
||||
for (const auto participantPeer : stop) {
|
||||
const auto i = ranges::find(
|
||||
_participants,
|
||||
participantPeer,
|
||||
&Participant::peer);
|
||||
if (i->speaking) {
|
||||
const auto was = *i;
|
||||
i->speaking = false;
|
||||
const auto participant = findParticipant(participantPeer);
|
||||
Assert(participant != nullptr);
|
||||
if (participant->speaking) {
|
||||
const auto was = *participant;
|
||||
participant->speaking = false;
|
||||
_participantUpdates.fire({
|
||||
.was = was,
|
||||
.now = *i,
|
||||
.now = *participant,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -108,6 +108,8 @@ public:
|
|||
[[nodiscard]] PeerData *participantPeerByAudioSsrc(uint32 ssrc) const;
|
||||
[[nodiscard]] PeerData *participantPeerByCameraSsrc(uint32 ssrc) const;
|
||||
[[nodiscard]] PeerData *participantPeerByScreenSsrc(uint32 ssrc) const;
|
||||
[[nodiscard]] const Participant *participantByPeer(
|
||||
not_null<PeerData*> peer) const;
|
||||
[[nodiscard]] const Participant *participantByEndpoint(
|
||||
const std::string &endpoint) const;
|
||||
|
||||
|
@ -178,6 +180,7 @@ private:
|
|||
const MTPphone_GroupCall &call) const;
|
||||
[[nodiscard]] bool processSavedFullCall();
|
||||
void finishParticipantsSliceRequest();
|
||||
[[nodiscard]] Participant *findParticipant(not_null<PeerData*> peer);
|
||||
|
||||
void emplaceVideoSsrcs(const Participant &participant);
|
||||
void eraseVideoSsrcs(const Participant &participant);
|
||||
|
|
Loading…
Add table
Reference in a new issue