Update self as channel in voice chats.

This commit is contained in:
John Preston 2021-03-05 15:36:07 +04:00
parent 02e9b8fd18
commit 4d093f78e2
11 changed files with 118 additions and 67 deletions

View file

@ -1207,7 +1207,7 @@ groupCall#c0c2052e 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;
groupCallParticipant#d27d3adf 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 peer:Peer date:int active_date:flags.3?int source:int volume:flags.7?int about:flags.11?string = GroupCallParticipant; groupCallParticipant#7c48057b 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 peer:Peer date:int active_date:flags.3?int source:flags.12?int volume:flags.7?int about:flags.11?string raise_hand_rating:flags.13?long = GroupCallParticipant;
phone.groupCall#9e727aad call:GroupCall participants:Vector<GroupCallParticipant> participants_next_offset:string chats:Vector<Chat> users:Vector<User> = phone.GroupCall; phone.groupCall#9e727aad call:GroupCall participants:Vector<GroupCallParticipant> participants_next_offset:string chats:Vector<Chat> users:Vector<User> = phone.GroupCall;
@ -1611,8 +1611,8 @@ phone.discardCall#b2cbc1c0 flags:# video:flags.0?true peer:InputPhoneCall durati
phone.setCallRating#59ead627 flags:# user_initiative:flags.0?true peer:InputPhoneCall rating:int comment:string = Updates; phone.setCallRating#59ead627 flags:# user_initiative:flags.0?true peer:InputPhoneCall rating:int comment:string = Updates;
phone.saveCallDebug#277add7e peer:InputPhoneCall debug:DataJSON = Bool; phone.saveCallDebug#277add7e peer:InputPhoneCall debug:DataJSON = Bool;
phone.sendSignalingData#ff7a9383 peer:InputPhoneCall data:bytes = Bool; phone.sendSignalingData#ff7a9383 peer:InputPhoneCall data:bytes = Bool;
phone.createGroupCall#1fd59252 flags:# peer:InputPeer join_as:flags.0?InputPeer random_id:int = Updates; phone.createGroupCall#7c068f5 peer:InputPeer join_as:InputPeer random_id:int = Updates;
phone.joinGroupCall#2e8166b8 flags:# muted:flags.0?true call:InputGroupCall join_as:flags.1?InputPeer params:DataJSON = Updates; phone.joinGroupCall#3633a5b0 flags:# muted:flags.0?true call:InputGroupCall join_as:InputPeer params:DataJSON = Updates;
phone.leaveGroupCall#500377f9 call:InputGroupCall source:int = Updates; phone.leaveGroupCall#500377f9 call:InputGroupCall source:int = Updates;
phone.inviteToGroupCall#7b393160 call:InputGroupCall users:Vector<InputUser> = Updates; phone.inviteToGroupCall#7b393160 call:InputGroupCall users:Vector<InputUser> = Updates;
phone.discardGroupCall#7a777135 call:InputGroupCall = Updates; phone.discardGroupCall#7a777135 call:InputGroupCall = Updates;
@ -1621,7 +1621,7 @@ phone.getGroupCall#c7cb017 call:InputGroupCall = phone.GroupCall;
phone.getGroupParticipants#c9f1d285 call:InputGroupCall ids:Vector<int> sources:Vector<int> offset:string limit:int = phone.GroupParticipants; phone.getGroupParticipants#c9f1d285 call:InputGroupCall ids:Vector<int> sources:Vector<int> offset:string limit:int = phone.GroupParticipants;
phone.checkGroupCall#b74a7bea call:InputGroupCall source:int = Bool; phone.checkGroupCall#b74a7bea call:InputGroupCall source:int = Bool;
phone.toggleGroupCallRecord#c02a66d7 flags:# start:flags.0?true call:InputGroupCall title:flags.1?string = Updates; phone.toggleGroupCallRecord#c02a66d7 flags:# start:flags.0?true call:InputGroupCall title:flags.1?string = Updates;
phone.editGroupCallParticipant#4713e7a3 flags:# muted:flags.0?true call:InputGroupCall participant:InputPeer volume:flags.1?int = Updates; phone.editGroupCallParticipant#d975eb80 flags:# muted:flags.0?true call:InputGroupCall participant:InputPeer volume:flags.1?int raise_hand:flags.2?Bool = Updates;
phone.editGroupCallTitle#1ca6ac0a call:InputGroupCall title:string = Updates; phone.editGroupCallTitle#1ca6ac0a call:InputGroupCall title:string = Updates;
langpack.getLangPack#f2f2330a lang_pack:string lang_code:string = LangPackDifference; langpack.getLangPack#f2f2330a lang_pack:string lang_code:string = LangPackDifference;

View file

@ -705,6 +705,10 @@ void PeerListRow::setCheckedInternal(bool checked, anim::type animated) {
_checkbox->setChecked(checked, animated); _checkbox->setChecked(checked, animated);
} }
void PeerListRow::finishCheckedAnimation() {
_checkbox->setChecked(_checkbox->checked(), anim::type::instant);
}
PeerListContent::PeerListContent( PeerListContent::PeerListContent(
QWidget *parent, QWidget *parent,
not_null<PeerListController*> controller) not_null<PeerListController*> controller)

View file

@ -169,6 +169,7 @@ public:
} }
setCheckedInternal(checked, animated); setCheckedInternal(checked, animated);
} }
void finishCheckedAnimation();
void invalidatePixmapsCache(); void invalidatePixmapsCache();
template <typename UpdateCallback> template <typename UpdateCallback>

View file

@ -82,6 +82,7 @@ void ListController::prepare() {
delegate()->peerListAppendRow(std::move(row)); delegate()->peerListAppendRow(std::move(row));
if (peer == _selected) { if (peer == _selected) {
delegate()->peerListSetRowChecked(raw, true); delegate()->peerListSetRowChecked(raw, true);
raw->finishCheckedAnimation();
} }
} }
delegate()->peerListRefreshRows(); delegate()->peerListRefreshRows();
@ -136,9 +137,7 @@ void ChooseJoinAsBox(
delegate->setContent(content); delegate->setContent(content);
controller->setDelegate(delegate); controller->setDelegate(delegate);
box->addButton(tr::lng_continue(), [=] { box->addButton(tr::lng_continue(), [=] {
const auto selected = controller->selected(); done(controller->selected());
box->closeBox();
done(selected);
}); });
box->addButton(tr::lng_cancel(), [=] { box->closeBox(); }); box->addButton(tr::lng_cancel(), [=] { box->closeBox(); });
} }
@ -184,8 +183,12 @@ void ChooseJoinAsProcess::start(
const auto finish = [=](not_null<PeerData*> joinAs) { const auto finish = [=](not_null<PeerData*> joinAs) {
const auto peer = _request->peer; const auto peer = _request->peer;
const auto done = std::move(_request->done); const auto done = std::move(_request->done);
const auto box = _request->box;
_request = nullptr; _request = nullptr;
done(peer, joinAs); done(peer, joinAs);
if (const auto strong = box.data()) {
strong->closeBox();
}
}; };
using Flag = MTPchannels_GetAdminedPublicChannels::Flag; using Flag = MTPchannels_GetAdminedPublicChannels::Flag;
_request->id = session->api().request( _request->id = session->api().request(
@ -217,7 +220,7 @@ void ChooseJoinAsProcess::start(
? not_null(loaded) ? not_null(loaded)
: self; : self;
}(); }();
Ui::show( _request->box = Ui::show(
Box( Box(
ChooseJoinAsBox, ChooseJoinAsBox,
_request->context, _request->context,
@ -225,6 +228,11 @@ void ChooseJoinAsProcess::start(
selected, selected,
crl::guard(&_request->guard, finish)), crl::guard(&_request->guard, finish)),
Ui::LayerOption::KeepOther); Ui::LayerOption::KeepOther);
_request->box->boxClosing(
) | rpl::start_with_next([=] {
_request = nullptr;
}, _request->lifetime);
}).fail([=](const RPCError &error) { }).fail([=](const RPCError &error) {
finish(session->user()); finish(session->user());
}).send(); }).send();

View file

@ -11,6 +11,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
class PeerData; class PeerData;
namespace Ui {
class BoxContent;
} // namespace Ui
namespace Calls { namespace Calls {
class ChooseJoinAsProcess final { class ChooseJoinAsProcess final {
@ -34,6 +38,7 @@ private:
not_null<PeerData*> peer; not_null<PeerData*> peer;
Fn<void(not_null<PeerData*>, not_null<PeerData*>)> done; Fn<void(not_null<PeerData*>, not_null<PeerData*>)> done;
base::has_weak_ptr guard; base::has_weak_ptr guard;
QPointer<Ui::BoxContent> box;
rpl::lifetime lifetime; rpl::lifetime lifetime;
Context context = Context(); Context context = Context();
mtpRequestId id = 0; mtpRequestId id = 0;

View file

@ -246,7 +246,6 @@ void GroupCall::playConnectingSoundOnce() {
void GroupCall::start() { void GroupCall::start() {
_createRequestId = _api.request(MTPphone_CreateGroupCall( _createRequestId = _api.request(MTPphone_CreateGroupCall(
MTP_flags(MTPphone_CreateGroupCall::Flag::f_join_as),
_peer->input, _peer->input,
_joinAs->input, _joinAs->input,
MTP_int(openssl::RandomValue<int32>()) MTP_int(openssl::RandomValue<int32>())
@ -321,7 +320,7 @@ void GroupCall::rejoin() {
_mySsrc = 0; _mySsrc = 0;
setState(State::Joining); setState(State::Joining);
createAndStartController(); createAndStartController();
applySelfInCallLocally(); applyMeInCallLocally();
LOG(("Call Info: Requesting join payload.")); LOG(("Call Info: Requesting join payload."));
const auto weak = base::make_weak(this); const auto weak = base::make_weak(this);
@ -353,10 +352,9 @@ void GroupCall::rejoin() {
const auto wasMuteState = muted(); const auto wasMuteState = muted();
using Flag = MTPphone_JoinGroupCall::Flag; using Flag = MTPphone_JoinGroupCall::Flag;
_api.request(MTPphone_JoinGroupCall( _api.request(MTPphone_JoinGroupCall(
MTP_flags(Flag::f_join_as MTP_flags((wasMuteState != MuteState::Active)
| (wasMuteState != MuteState::Active ? Flag::f_muted
? Flag::f_muted : Flag(0)),
: Flag(0))),
inputCall(), inputCall(),
_joinAs->input, _joinAs->input,
MTP_dataJSON(MTP_bytes(json)) MTP_dataJSON(MTP_bytes(json))
@ -365,7 +363,7 @@ void GroupCall::rejoin() {
setState(_instanceConnected setState(_instanceConnected
? State::Joined ? State::Joined
: State::Connecting); : State::Connecting);
applySelfInCallLocally(); applyMeInCallLocally();
maybeSendMutedUpdate(wasMuteState); maybeSendMutedUpdate(wasMuteState);
_peer->session().api().applyUpdates(updates); _peer->session().api().applyUpdates(updates);
}).fail([=](const RPCError &error) { }).fail([=](const RPCError &error) {
@ -392,17 +390,16 @@ void GroupCall::rejoin() {
}); });
} }
void GroupCall::applySelfInCallLocally() { void GroupCall::applyMeInCallLocally() {
const auto call = _peer->groupCall(); const auto call = _peer->groupCall();
if (!call || call->id() != _id) { if (!call || call->id() != _id) {
return; return;
} }
using Flag = MTPDgroupCallParticipant::Flag; using Flag = MTPDgroupCallParticipant::Flag;
const auto &participants = call->participants(); const auto &participants = call->participants();
const auto self = _peer->session().user();
const auto i = ranges::find( const auto i = ranges::find(
participants, participants,
self, _joinAs,
&Data::GroupCall::Participant::peer); &Data::GroupCall::Participant::peer);
const auto date = (i != end(participants)) const auto date = (i != end(participants))
? i->date ? i->date
@ -428,12 +425,13 @@ void GroupCall::applySelfInCallLocally() {
1, 1,
MTP_groupCallParticipant( MTP_groupCallParticipant(
MTP_flags(flags), MTP_flags(flags),
peerToMTP(self->id), // #TODO calls channel or self peerToMTP(_joinAs->id),
MTP_int(date), MTP_int(date),
MTP_int(lastActive), MTP_int(lastActive),
MTP_int(_mySsrc), MTP_int(_mySsrc),
MTP_int(volume), MTP_int(volume),
MTPstring())), // #TODO calls about MTPstring(), // #TODO calls about
MTPlong())), // #TODO calls raise hand rating
MTP_int(0)).c_updateGroupCallParticipants()); MTP_int(0)).c_updateGroupCallParticipants());
} }
@ -460,7 +458,8 @@ void GroupCall::applyParticipantLocally(
: Flag(0)) : Flag(0))
| (participant->lastActive ? Flag::f_active_date : Flag(0)) | (participant->lastActive ? Flag::f_active_date : Flag(0))
| (isMuted ? Flag::f_muted : Flag(0)) | (isMuted ? Flag::f_muted : Flag(0))
| (isMutedByYou ? Flag::f_muted_by_you : Flag(0)); // #TODO calls self? | (isMutedByYou ? Flag::f_muted_by_you : Flag(0))
| (participantPeer == _joinAs ? Flag::f_self : Flag(0));
_peer->groupCall()->applyUpdateChecked( _peer->groupCall()->applyUpdateChecked(
MTP_updateGroupCallParticipants( MTP_updateGroupCallParticipants(
inputCall(), inputCall(),
@ -473,7 +472,8 @@ void GroupCall::applyParticipantLocally(
MTP_int(participant->lastActive), MTP_int(participant->lastActive),
MTP_int(participant->ssrc), MTP_int(participant->ssrc),
MTP_int(volume.value_or(participant->volume)), MTP_int(volume.value_or(participant->volume)),
MTPstring())), // #TODO calls about MTPstring(), // #TODO calls about
MTPlong())), // #TODO calls raise hand rating
MTP_int(0)).c_updateGroupCallParticipants()); MTP_int(0)).c_updateGroupCallParticipants());
} }
@ -547,7 +547,7 @@ void GroupCall::setMuted(MuteState mute) {
const auto nowMuted = (muted() == MuteState::Muted) const auto nowMuted = (muted() == MuteState::Muted)
|| (muted() == MuteState::PushToTalk); || (muted() == MuteState::PushToTalk);
if (wasMuted != nowMuted) { if (wasMuted != nowMuted) {
applySelfInCallLocally(); applyMeInCallLocally();
} }
}; };
if (mute == MuteState::Active || mute == MuteState::PushToTalk) { if (mute == MuteState::Active || mute == MuteState::PushToTalk) {
@ -667,15 +667,15 @@ void GroupCall::handleUpdate(const MTPDupdateGroupCallParticipants &data) {
handleOtherParticipants(data); handleOtherParticipants(data);
return; return;
} }
if (data.is_left() && data.vsource().v == _mySsrc) { if (data.is_left() && data.vsource().value_or_empty() == _mySsrc) {
// I was removed from the call, rejoin. // I was removed from the call, rejoin.
LOG(("Call Info: Rejoin after got 'left' with my ssrc.")); LOG(("Call Info: Rejoin after got 'left' with my ssrc."));
setState(State::Joining); setState(State::Joining);
rejoin(); rejoin();
} else if (!data.is_left() && data.vsource().v != _mySsrc) { } else if (!data.is_left() && data.vsource().value_or_empty() != _mySsrc) {
// I joined from another device, hangup. // I joined from another device, hangup.
LOG(("Call Info: Hangup after '!left' with ssrc %1, my %2." LOG(("Call Info: Hangup after '!left' with ssrc %1, my %2."
).arg(data.vsource().v ).arg(data.vsource().value_or_empty()
).arg(_mySsrc)); ).arg(_mySsrc));
_mySsrc = 0; _mySsrc = 0;
hangup(); hangup();
@ -785,17 +785,17 @@ void GroupCall::audioLevelsUpdated(const tgcalls::GroupLevelsUpdate &data) {
const auto ssrc = ssrcOrZero ? ssrcOrZero : _mySsrc; const auto ssrc = ssrcOrZero ? ssrcOrZero : _mySsrc;
const auto level = value.level; const auto level = value.level;
const auto voice = value.voice; const auto voice = value.voice;
const auto self = (ssrc == _mySsrc); const auto me = (ssrc == _mySsrc);
_levelUpdates.fire(LevelUpdate{ _levelUpdates.fire(LevelUpdate{
.ssrc = ssrc, .ssrc = ssrc,
.value = level, .value = level,
.voice = voice, .voice = voice,
.self = self .me = me
}); });
if (level <= kSpeakLevelThreshold) { if (level <= kSpeakLevelThreshold) {
continue; continue;
} }
if (self if (me
&& voice && voice
&& (!_lastSendProgressUpdate && (!_lastSendProgressUpdate
|| _lastSendProgressUpdate + kUpdateSendActionEach < now)) { || _lastSendProgressUpdate + kUpdateSendActionEach < now)) {
@ -912,8 +912,9 @@ void GroupCall::sendMutedUpdate() {
_updateMuteRequestId = _api.request(MTPphone_EditGroupCallParticipant( _updateMuteRequestId = _api.request(MTPphone_EditGroupCallParticipant(
MTP_flags((muted() != MuteState::Active) ? Flag::f_muted : Flag(0)), MTP_flags((muted() != MuteState::Active) ? Flag::f_muted : Flag(0)),
inputCall(), inputCall(),
MTP_inputPeerSelf(), _joinAs->input,
MTP_int(100000) // volume MTP_int(100000), // volume
MTPBool() // #TODO calls raise_hand
)).done([=](const MTPUpdates &result) { )).done([=](const MTPUpdates &result) {
_updateMuteRequestId = 0; _updateMuteRequestId = 0;
_peer->session().api().applyUpdates(result); _peer->session().api().applyUpdates(result);
@ -977,7 +978,8 @@ void GroupCall::editParticipant(
MTP_flags(flags), MTP_flags(flags),
inputCall(), inputCall(),
participantPeer->input, participantPeer->input,
MTP_int(std::clamp(volume.value_or(0), 1, Group::kMaxVolume)) MTP_int(std::clamp(volume.value_or(0), 1, Group::kMaxVolume)),
MTPBool() // #TODO calls raise_hand
)).done([=](const MTPUpdates &result) { )).done([=](const MTPUpdates &result) {
_peer->session().api().applyUpdates(result); _peer->session().api().applyUpdates(result);
}).fail([=](const RPCError &error) { }).fail([=](const RPCError &error) {

View file

@ -62,7 +62,7 @@ struct LevelUpdate {
uint32 ssrc = 0; uint32 ssrc = 0;
float value = 0.; float value = 0.;
bool voice = false; bool voice = false;
bool self = false; bool me = false;
}; };
class GroupCall final : public base::has_weak_ptr { class GroupCall final : public base::has_weak_ptr {
@ -99,6 +99,9 @@ public:
[[nodiscard]] not_null<PeerData*> peer() const { [[nodiscard]] not_null<PeerData*> peer() const {
return _peer; return _peer;
} }
[[nodiscard]] not_null<PeerData*> joinAs() const {
return _joinAs;
}
void start(); void start();
void hangup(); void hangup();
@ -179,7 +182,7 @@ private:
void sendMutedUpdate(); void sendMutedUpdate();
void updateInstanceMuteState(); void updateInstanceMuteState();
void updateInstanceVolumes(); void updateInstanceVolumes();
void applySelfInCallLocally(); void applyMeInCallLocally();
void rejoin(); void rejoin();
void audioLevelsUpdated(const tgcalls::GroupLevelsUpdate &data); void audioLevelsUpdated(const tgcalls::GroupLevelsUpdate &data);

View file

@ -78,6 +78,7 @@ class Row;
class RowDelegate { class RowDelegate {
public: public:
virtual bool rowIsMe(not_null<PeerData*> participantPeer) = 0;
virtual bool rowCanMuteMembers() = 0; virtual bool rowCanMuteMembers() = 0;
virtual void rowUpdateRow(not_null<Row*> row) = 0; virtual void rowUpdateRow(not_null<Row*> row) = 0;
virtual void rowPaintIcon( virtual void rowPaintIcon(
@ -135,7 +136,7 @@ public:
st::groupCallActiveButton.height); st::groupCallActiveButton.height);
} }
bool actionDisabled() const override { bool actionDisabled() const override {
return peer()->isSelf() return _delegate->rowIsMe(peer())
|| (_state == State::Invited) || (_state == State::Invited)
|| !_delegate->rowCanMuteMembers(); || !_delegate->rowCanMuteMembers();
} }
@ -271,6 +272,7 @@ public:
[[nodiscard]] auto kickParticipantRequests() const [[nodiscard]] auto kickParticipantRequests() const
-> rpl::producer<not_null<PeerData*>>; -> rpl::producer<not_null<PeerData*>>;
bool rowIsMe(not_null<PeerData*> participantPeer) override;
bool rowCanMuteMembers() override; bool rowCanMuteMembers() override;
void rowUpdateRow(not_null<Row*> row) override; void rowUpdateRow(not_null<Row*> row) override;
void rowPaintIcon( void rowPaintIcon(
@ -282,12 +284,13 @@ public:
bool mutedByMe) override; bool mutedByMe) override;
private: private:
[[nodiscard]] std::unique_ptr<Row> createSelfRow(); [[nodiscard]] std::unique_ptr<Row> createRowForMe();
[[nodiscard]] std::unique_ptr<Row> createRow( [[nodiscard]] std::unique_ptr<Row> createRow(
const Data::GroupCall::Participant &participant); const Data::GroupCall::Participant &participant);
[[nodiscard]] std::unique_ptr<Row> createInvitedRow( [[nodiscard]] std::unique_ptr<Row> createInvitedRow(
not_null<PeerData*> participantPeer); not_null<PeerData*> participantPeer);
[[nodiscard]] bool isMe(not_null<PeerData*> participantPeer) const;
void prepareRows(not_null<Data::GroupCall*> real); void prepareRows(not_null<Data::GroupCall*> real);
//void repaintByTimer(); //void repaintByTimer();
@ -690,7 +693,7 @@ void Row::paintStatusText(
outerWidth, outerWidth,
(_state == State::MutedByMe (_state == State::MutedByMe
? tr::lng_group_call_muted_by_me_status(tr::now) ? tr::lng_group_call_muted_by_me_status(tr::now)
: peer()->isSelf() : _delegate->rowIsMe(peer())
? tr::lng_status_connecting(tr::now) ? tr::lng_status_connecting(tr::now)
: tr::lng_group_call_invited_status(tr::now))); : tr::lng_group_call_invited_status(tr::now)));
} }
@ -882,9 +885,12 @@ void MembersController::subscribeToChanges(not_null<Data::GroupCall*> real) {
if (!update.now) { if (!update.now) {
if (const auto row = findRow(participantPeer)) { if (const auto row = findRow(participantPeer)) {
const auto owner = &participantPeer->owner(); const auto owner = &participantPeer->owner();
if (participantPeer->isSelf()) { if (isMe(participantPeer)) {
updateRow(row, nullptr); updateRow(row, nullptr);
} else { } else {
if (const auto min = _fullCountMin.current()) {
_fullCountMin = min - 1;
}
removeRow(row); removeRow(row);
delegate()->peerListRefreshRows(); delegate()->peerListRefreshRows();
} }
@ -1008,6 +1014,7 @@ void MembersController::updateRow(
const Data::GroupCall::Participant *participant) { const Data::GroupCall::Participant *participant) {
const auto wasSounding = row->sounding(); const auto wasSounding = row->sounding();
const auto wasSsrc = row->ssrc(); const auto wasSsrc = row->ssrc();
const auto wasInChat = (row->state() != Row::State::Invited);
row->setSkipLevelUpdate(_skipRowLevelUpdate); row->setSkipLevelUpdate(_skipRowLevelUpdate);
row->updateState(participant); row->updateState(participant);
const auto nowSounding = row->sounding(); const auto nowSounding = row->sounding();
@ -1036,6 +1043,11 @@ void MembersController::updateRow(
_soundingAnimation.stop(); _soundingAnimation.stop();
} }
if (!participant && wasInChat) {
if (const auto min = _fullCountMin.current()) {
_fullCountMin = min - 1;
}
}
delegate()->peerListUpdateRow(row); delegate()->peerListUpdateRow(row);
} }
@ -1080,7 +1092,7 @@ void MembersController::prepare() {
if (const auto real = _peer->groupCall() if (const auto real = _peer->groupCall()
; real && call && real->id() == call->id()) { ; real && call && real->id() == call->id()) {
prepareRows(real); prepareRows(real);
} else if (auto row = createSelfRow()) { } else if (auto row = createRowForMe()) {
_fullCountMin = (row->state() == Row::State::Invited) ? 0 : 1; _fullCountMin = (row->state() == Row::State::Invited) ? 0 : 1;
delegate()->peerListAppendRow(std::move(row)); delegate()->peerListAppendRow(std::move(row));
delegate()->peerListRefreshRows(); delegate()->peerListRefreshRows();
@ -1093,8 +1105,13 @@ void MembersController::prepare() {
_prepared = true; _prepared = true;
} }
bool MembersController::isMe(not_null<PeerData*> participantPeer) const {
const auto call = _call.get();
return call && (call->joinAs() == participantPeer);
}
void MembersController::prepareRows(not_null<Data::GroupCall*> real) { void MembersController::prepareRows(not_null<Data::GroupCall*> real) {
auto foundSelf = false; auto foundMe = false;
auto changed = false; auto changed = false;
const auto &participants = real->participants(); const auto &participants = real->participants();
auto fullCountMin = 0; auto fullCountMin = 0;
@ -1102,8 +1119,8 @@ void MembersController::prepareRows(not_null<Data::GroupCall*> real) {
for (auto i = 0; i != count;) { for (auto i = 0; i != count;) {
auto row = delegate()->peerListRowAt(i); auto row = delegate()->peerListRowAt(i);
auto participantPeer = row->peer(); auto participantPeer = row->peer();
if (participantPeer->isSelf()) { // #TODO calls add self even if channel if (isMe(participantPeer)) {
foundSelf = true; foundMe = true;
++i; ++i;
continue; continue;
} }
@ -1120,19 +1137,23 @@ void MembersController::prepareRows(not_null<Data::GroupCall*> real) {
--count; --count;
} }
} }
if (!foundSelf) { if (!foundMe) {
const auto self = _peer->session().user(); if (const auto call = _call.get()) {
const auto i = ranges::find( const auto me = call->joinAs();
participants, const auto i = ranges::find(
self, participants,
&Data::GroupCall::Participant::peer); me,
auto row = (i != end(participants)) ? createRow(*i) : createSelfRow(); &Data::GroupCall::Participant::peer);
if (row) { auto row = (i != end(participants))
if (row->state() != Row::State::Invited) { ? createRow(*i)
++fullCountMin; : createRowForMe();
if (row) {
if (row->state() != Row::State::Invited) {
++fullCountMin;
}
changed = true;
delegate()->peerListAppendRow(std::move(row));
} }
changed = true;
delegate()->peerListAppendRow(std::move(row));
} }
} }
for (const auto &participant : participants) { for (const auto &participant : participants) {
@ -1170,6 +1191,10 @@ auto MembersController::changeVolumeRequests() const
return _changeVolumeRequests.events(); return _changeVolumeRequests.events();
} }
bool MembersController::rowIsMe(not_null<PeerData*> participantPeer) {
return isMe(participantPeer);
}
bool MembersController::rowCanMuteMembers() { bool MembersController::rowCanMuteMembers() {
return _peer->canManageGroupCall(); return _peer->canManageGroupCall();
} }
@ -1279,7 +1304,7 @@ base::unique_qptr<Ui::PopupMenu> MembersController::createRowContextMenu(
not_null<PeerListRow*> row) { not_null<PeerListRow*> row) {
const auto participantPeer = row->peer(); const auto participantPeer = row->peer();
const auto real = static_cast<Row*>(row.get()); const auto real = static_cast<Row*>(row.get());
if (participantPeer->isSelf() if (isMe(participantPeer)
&& (!_peer->canManageGroupCall() || !real->ssrc())) { && (!_peer->canManageGroupCall() || !real->ssrc())) {
return nullptr; return nullptr;
} }
@ -1342,7 +1367,7 @@ base::unique_qptr<Ui::PopupMenu> MembersController::createRowContextMenu(
addMuteActionsToContextMenu(result, participantPeer, admin, real); addMuteActionsToContextMenu(result, participantPeer, admin, real);
} }
if (!participantPeer->isSelf()) { // #TODO calls correct check self if (!isMe(participantPeer)) {
result->addAction( result->addAction(
tr::lng_context_view_profile(tr::now), tr::lng_context_view_profile(tr::now),
showProfile); showProfile);
@ -1418,8 +1443,8 @@ void MembersController::addMuteActionsToContextMenu(
auto mutesFromVolume = rpl::never<bool>() | rpl::type_erased(); auto mutesFromVolume = rpl::never<bool>() | rpl::type_erased();
if (!isMuted || participantPeer->isSelf()) { const auto call = _call.get();
const auto call = _call.get(); if (!isMuted || (call && call->joinAs() == participantPeer)) {
auto otherParticipantStateValue = call auto otherParticipantStateValue = call
? call->otherParticipantStateValue( ? call->otherParticipantStateValue(
) | rpl::filter([=](const Group::ParticipantState &data) { ) | rpl::filter([=](const Group::ParticipantState &data) {
@ -1451,7 +1476,7 @@ void MembersController::addMuteActionsToContextMenu(
volumeItem->toggleMuteLocallyRequests( volumeItem->toggleMuteLocallyRequests(
) | rpl::start_with_next([=](bool muted) { ) | rpl::start_with_next([=](bool muted) {
if (!participantPeer->isSelf()) { // #TODO calls check self if (!isMe(participantPeer)) {
toggleMute(muted, true); toggleMute(muted, true);
} }
}, volumeItem->lifetime()); }, volumeItem->lifetime());
@ -1463,7 +1488,7 @@ void MembersController::addMuteActionsToContextMenu(
volumeItem->changeVolumeLocallyRequests( volumeItem->changeVolumeLocallyRequests(
) | rpl::start_with_next([=](int volume) { ) | rpl::start_with_next([=](int volume) {
if (!participantPeer->isSelf()) { // #TODO calls check self if (!isMe(participantPeer)) {
changeVolume(volume, true); changeVolume(volume, true);
} }
}, volumeItem->lifetime()); }, volumeItem->lifetime());
@ -1473,7 +1498,7 @@ void MembersController::addMuteActionsToContextMenu(
const auto muteAction = [&]() -> QAction* { const auto muteAction = [&]() -> QAction* {
if (muteState == Row::State::Invited if (muteState == Row::State::Invited
|| participantPeer->isSelf() // #TODO calls check self || isMe(participantPeer)
|| (muteState == Row::State::Muted || (muteState == Row::State::Muted
&& participantIsCallAdmin && participantIsCallAdmin
&& _peer->canManageGroupCall())) { && _peer->canManageGroupCall())) {
@ -1499,9 +1524,12 @@ void MembersController::addMuteActionsToContextMenu(
} }
} }
std::unique_ptr<Row> MembersController::createSelfRow() { std::unique_ptr<Row> MembersController::createRowForMe() {
const auto self = _peer->session().user(); // #TODO calls check self const auto call = _call.get();
auto result = std::make_unique<Row>(this, self); if (!call) {
return nullptr;
}
auto result = std::make_unique<Row>(this, call->joinAs());
updateRow(result.get(), nullptr); updateRow(result.get(), nullptr);
return result; return result;
} }

View file

@ -501,7 +501,7 @@ void GroupPanel::initWithCall(GroupCall *call) {
call->levelUpdates( call->levelUpdates(
) | rpl::filter([=](const LevelUpdate &update) { ) | rpl::filter([=](const LevelUpdate &update) {
return update.self; return update.me;
}) | rpl::start_with_next([=](const LevelUpdate &update) { }) | rpl::start_with_next([=](const LevelUpdate &update) {
_mute->setLevel(update.value); _mute->setLevel(update.value);
}, _callLifetime); }, _callLifetime);

View file

@ -296,7 +296,7 @@ void GroupCall::applyParticipantsSlice(
.peer = participantPeer, .peer = participantPeer,
.date = data.vdate().v, .date = data.vdate().v,
.lastActive = lastActive, .lastActive = lastActive,
.ssrc = uint32(data.vsource().v), .ssrc = uint32(data.vsource().value_or_empty()),
.volume = volume, .volume = volume,
.applyVolumeFromMin = applyVolumeFromMin, .applyVolumeFromMin = applyVolumeFromMin,
.speaking = canSelfUnmute && (was ? was->speaking : false), .speaking = canSelfUnmute && (was ? was->speaking : false),

View file

@ -56,7 +56,6 @@ public:
-> const std::vector<Participant> &; -> const std::vector<Participant> &;
void requestParticipants(); void requestParticipants();
[[nodiscard]] bool participantsLoaded() const; [[nodiscard]] bool participantsLoaded() const;
[[nodiscard]] PeerData *participantPeerBySsrc(uint32 ssrc) const;
[[nodiscard]] rpl::producer<> participantsSliceAdded(); [[nodiscard]] rpl::producer<> participantsSliceAdded();
[[nodiscard]] rpl::producer<ParticipantUpdate> participantUpdated() const; [[nodiscard]] rpl::producer<ParticipantUpdate> participantUpdated() const;
@ -97,6 +96,7 @@ private:
void requestUnknownParticipants(); void requestUnknownParticipants();
void changePeerEmptyCallFlag(); void changePeerEmptyCallFlag();
void checkFinishSpeakingByActive(); void checkFinishSpeakingByActive();
[[nodiscard]] PeerData *participantPeerBySsrc(uint32 ssrc) const;
const uint64 _id = 0; const uint64 _id = 0;
const uint64 _accessHash = 0; const uint64 _accessHash = 0;