mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Special mute state for Push-to-Talk unmute.
This commit is contained in:
parent
8f11868bb6
commit
af4f10b1bb
4 changed files with 62 additions and 32 deletions
|
@ -53,13 +53,14 @@ GroupCall::GroupCall(
|
||||||
, _api(&_channel->session().mtp())
|
, _api(&_channel->session().mtp())
|
||||||
, _lastSpokeCheckTimer([=] { checkLastSpoke(); })
|
, _lastSpokeCheckTimer([=] { checkLastSpoke(); })
|
||||||
, _checkJoinedTimer([=] { checkJoined(); }) {
|
, _checkJoinedTimer([=] { checkJoined(); }) {
|
||||||
_muted.changes(
|
_muted.value(
|
||||||
) | rpl::start_with_next([=](MuteState state) {
|
) | rpl::combine_previous(
|
||||||
|
) | rpl::start_with_next([=](MuteState previous, MuteState state) {
|
||||||
if (_instance) {
|
if (_instance) {
|
||||||
_instance->setIsMuted(state != MuteState::Active);
|
updateInstanceMuteState();
|
||||||
}
|
}
|
||||||
if (_mySsrc && state != MuteState::ForceMuted) {
|
if (_mySsrc) {
|
||||||
sendMutedUpdate();
|
maybeSendMutedUpdate(previous);
|
||||||
}
|
}
|
||||||
}, _lifetime);
|
}, _lifetime);
|
||||||
|
|
||||||
|
@ -200,9 +201,9 @@ void GroupCall::rejoin() {
|
||||||
|
|
||||||
const auto json = QJsonDocument(root).toJson(
|
const auto json = QJsonDocument(root).toJson(
|
||||||
QJsonDocument::Compact);
|
QJsonDocument::Compact);
|
||||||
const auto muted = _muted.current();
|
const auto wasMuteState = muted();
|
||||||
_api.request(MTPphone_JoinGroupCall(
|
_api.request(MTPphone_JoinGroupCall(
|
||||||
MTP_flags((muted != MuteState::Active)
|
MTP_flags((wasMuteState != MuteState::Active)
|
||||||
? MTPphone_JoinGroupCall::Flag::f_muted
|
? MTPphone_JoinGroupCall::Flag::f_muted
|
||||||
: MTPphone_JoinGroupCall::Flag(0)),
|
: MTPphone_JoinGroupCall::Flag(0)),
|
||||||
inputCall(),
|
inputCall(),
|
||||||
|
@ -213,11 +214,7 @@ void GroupCall::rejoin() {
|
||||||
? State::Joined
|
? State::Joined
|
||||||
: State::Connecting);
|
: State::Connecting);
|
||||||
applySelfInCallLocally();
|
applySelfInCallLocally();
|
||||||
|
maybeSendMutedUpdate(wasMuteState);
|
||||||
if (_muted.current() != muted) {
|
|
||||||
sendMutedUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
_channel->session().api().applyUpdates(updates);
|
_channel->session().api().applyUpdates(updates);
|
||||||
}).fail([=](const RPCError &error) {
|
}).fail([=](const RPCError &error) {
|
||||||
LOG(("Call Error: Could not join, error: %1"
|
LOG(("Call Error: Could not join, error: %1"
|
||||||
|
@ -251,12 +248,11 @@ void GroupCall::applySelfInCallLocally() {
|
||||||
const auto lastActive = (i != end(participants))
|
const auto lastActive = (i != end(participants))
|
||||||
? i->lastActive
|
? i->lastActive
|
||||||
: TimeId(0);
|
: TimeId(0);
|
||||||
const auto muted = (_muted.current() != MuteState::Active);
|
const auto canSelfUnmute = (muted() != MuteState::ForceMuted);
|
||||||
const auto cantSelfUnmute = (_muted.current() == MuteState::ForceMuted);
|
const auto flags = (canSelfUnmute ? Flag::f_can_self_unmute : Flag(0))
|
||||||
const auto flags = (cantSelfUnmute ? Flag(0) : Flag::f_can_self_unmute)
|
|
||||||
| (lastActive ? Flag::f_active_date : Flag(0))
|
| (lastActive ? Flag::f_active_date : Flag(0))
|
||||||
| (_mySsrc ? Flag(0) : Flag::f_left)
|
| (_mySsrc ? Flag(0) : Flag::f_left)
|
||||||
| (muted ? Flag::f_muted : Flag(0));
|
| ((muted() != MuteState::Active) ? Flag::f_muted : Flag(0));
|
||||||
call->applyUpdateChecked(
|
call->applyUpdateChecked(
|
||||||
MTP_updateGroupCallParticipants(
|
MTP_updateGroupCallParticipants(
|
||||||
inputCall(),
|
inputCall(),
|
||||||
|
@ -488,11 +484,19 @@ void GroupCall::createAndStartController() {
|
||||||
LOG(("Call Info: Creating group instance"));
|
LOG(("Call Info: Creating group instance"));
|
||||||
_instance = std::make_unique<tgcalls::GroupInstanceImpl>(
|
_instance = std::make_unique<tgcalls::GroupInstanceImpl>(
|
||||||
std::move(descriptor));
|
std::move(descriptor));
|
||||||
_instance->setIsMuted(_muted.current() != MuteState::Active);
|
updateInstanceMuteState();
|
||||||
|
|
||||||
//raw->setAudioOutputDuckingEnabled(settings.callAudioDuckingEnabled());
|
//raw->setAudioOutputDuckingEnabled(settings.callAudioDuckingEnabled());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GroupCall::updateInstanceMuteState() {
|
||||||
|
Expects(_instance != nullptr);
|
||||||
|
|
||||||
|
const auto state = muted();
|
||||||
|
_instance->setIsMuted(state != MuteState::Active
|
||||||
|
&& state != MuteState::PushToTalk);
|
||||||
|
}
|
||||||
|
|
||||||
void GroupCall::handleLevelsUpdated(
|
void GroupCall::handleLevelsUpdated(
|
||||||
gsl::span<const std::pair<std::uint32_t, float>> data) {
|
gsl::span<const std::pair<std::uint32_t, float>> data) {
|
||||||
Expects(!data.empty());
|
Expects(!data.empty());
|
||||||
|
@ -609,10 +613,23 @@ void GroupCall::setInstanceConnected(bool connected) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GroupCall::maybeSendMutedUpdate(MuteState previous) {
|
||||||
|
// Send only Active <-> !Active changes.
|
||||||
|
const auto now = muted();
|
||||||
|
const auto wasActive = (previous == MuteState::Active);
|
||||||
|
const auto nowActive = (now == MuteState::Active);
|
||||||
|
if (now == MuteState::ForceMuted
|
||||||
|
|| previous == MuteState::ForceMuted
|
||||||
|
|| (nowActive == wasActive)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sendMutedUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
void GroupCall::sendMutedUpdate() {
|
void GroupCall::sendMutedUpdate() {
|
||||||
_api.request(_updateMuteRequestId).cancel();
|
_api.request(_updateMuteRequestId).cancel();
|
||||||
_updateMuteRequestId = _api.request(MTPphone_EditGroupCallMember(
|
_updateMuteRequestId = _api.request(MTPphone_EditGroupCallMember(
|
||||||
MTP_flags((_muted.current() != MuteState::Active)
|
MTP_flags((muted() != MuteState::Active)
|
||||||
? MTPphone_EditGroupCallMember::Flag::f_muted
|
? MTPphone_EditGroupCallMember::Flag::f_muted
|
||||||
: MTPphone_EditGroupCallMember::Flag(0)),
|
: MTPphone_EditGroupCallMember::Flag(0)),
|
||||||
inputCall(),
|
inputCall(),
|
||||||
|
@ -758,8 +775,9 @@ void GroupCall::applyGlobalShortcutChanges() {
|
||||||
}
|
}
|
||||||
_pushToTalk = shortcut;
|
_pushToTalk = shortcut;
|
||||||
_shortcutManager->startWatching(_pushToTalk, [=](bool pressed) {
|
_shortcutManager->startWatching(_pushToTalk, [=](bool pressed) {
|
||||||
if (_muted.current() != MuteState::ForceMuted) {
|
if (muted() != MuteState::ForceMuted
|
||||||
setMuted(pressed ? MuteState::Active : MuteState::Muted);
|
&& muted() != MuteState::Active) {
|
||||||
|
setMuted(pressed ? MuteState::PushToTalk : MuteState::Muted);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,10 +28,17 @@ namespace Calls {
|
||||||
|
|
||||||
enum class MuteState {
|
enum class MuteState {
|
||||||
Active,
|
Active,
|
||||||
|
PushToTalk,
|
||||||
Muted,
|
Muted,
|
||||||
ForceMuted,
|
ForceMuted,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
[[nodiscard]] inline auto MapPushToTalkToActive() {
|
||||||
|
return rpl::map([=](MuteState state) {
|
||||||
|
return (state == MuteState::PushToTalk) ? MuteState::Active : state;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
struct LevelUpdate {
|
struct LevelUpdate {
|
||||||
uint32 ssrc = 0;
|
uint32 ssrc = 0;
|
||||||
float value = 0.;
|
float value = 0.;
|
||||||
|
@ -132,7 +139,9 @@ private:
|
||||||
|
|
||||||
void setState(State state);
|
void setState(State state);
|
||||||
void finish(FinishType type);
|
void finish(FinishType type);
|
||||||
|
void maybeSendMutedUpdate(MuteState previous);
|
||||||
void sendMutedUpdate();
|
void sendMutedUpdate();
|
||||||
|
void updateInstanceMuteState();
|
||||||
void applySelfInCallLocally();
|
void applySelfInCallLocally();
|
||||||
void rejoin();
|
void rejoin();
|
||||||
|
|
||||||
|
|
|
@ -317,13 +317,13 @@ void GroupPanel::hangup(bool discardCallChecked) {
|
||||||
void GroupPanel::initControls() {
|
void GroupPanel::initControls() {
|
||||||
_mute->clicks(
|
_mute->clicks(
|
||||||
) | rpl::filter([=](Qt::MouseButton button) {
|
) | rpl::filter([=](Qt::MouseButton button) {
|
||||||
return (button == Qt::LeftButton);
|
return (button == Qt::LeftButton)
|
||||||
|
&& _call
|
||||||
|
&& (_call->muted() != MuteState::ForceMuted);
|
||||||
}) | rpl::start_with_next([=] {
|
}) | rpl::start_with_next([=] {
|
||||||
if (_call && _call->muted() != MuteState::ForceMuted) {
|
_call->setMuted((_call->muted() == MuteState::Muted)
|
||||||
_call->setMuted((_call->muted() == MuteState::Active)
|
? MuteState::Active
|
||||||
? MuteState::Muted
|
: MuteState::Muted);
|
||||||
: MuteState::Active);
|
|
||||||
}
|
|
||||||
}, _mute->lifetime());
|
}, _mute->lifetime());
|
||||||
|
|
||||||
_hangup->setClickedCallback([=] { hangup(false); });
|
_hangup->setClickedCallback([=] { hangup(false); });
|
||||||
|
@ -381,19 +381,20 @@ void GroupPanel::initWithCall(GroupCall *call) {
|
||||||
|
|
||||||
using namespace rpl::mappers;
|
using namespace rpl::mappers;
|
||||||
rpl::combine(
|
rpl::combine(
|
||||||
_call->mutedValue(),
|
_call->mutedValue() | MapPushToTalkToActive(),
|
||||||
_call->stateValue() | rpl::map(
|
_call->stateValue() | rpl::map(
|
||||||
_1 == State::Creating
|
_1 == State::Creating
|
||||||
|| _1 == State::Joining
|
|| _1 == State::Joining
|
||||||
|| _1 == State::Connecting
|
|| _1 == State::Connecting
|
||||||
)
|
)
|
||||||
|
) | rpl::distinct_until_changed(
|
||||||
) | rpl::start_with_next([=](MuteState mute, bool connecting) {
|
) | rpl::start_with_next([=](MuteState mute, bool connecting) {
|
||||||
_mute->setState(Ui::CallMuteButtonState{
|
_mute->setState(Ui::CallMuteButtonState{
|
||||||
.text = (connecting
|
.text = (connecting
|
||||||
? tr::lng_group_call_connecting(tr::now)
|
? tr::lng_group_call_connecting(tr::now)
|
||||||
: mute == MuteState::ForceMuted
|
: mute == MuteState::ForceMuted
|
||||||
? tr::lng_group_call_force_muted(tr::now)
|
? tr::lng_group_call_force_muted(tr::now)
|
||||||
: mute != MuteState::Active
|
: mute == MuteState::Muted
|
||||||
? tr::lng_group_call_unmute(tr::now)
|
? tr::lng_group_call_unmute(tr::now)
|
||||||
: tr::lng_group_call_you_are_live(tr::now)),
|
: tr::lng_group_call_you_are_live(tr::now)),
|
||||||
.type = (connecting
|
.type = (connecting
|
||||||
|
|
|
@ -198,9 +198,9 @@ void TopBar::initControls() {
|
||||||
call->setMuted(!call->muted());
|
call->setMuted(!call->muted());
|
||||||
} else if (const auto group = _groupCall.get()) {
|
} else if (const auto group = _groupCall.get()) {
|
||||||
if (group->muted() != MuteState::ForceMuted) {
|
if (group->muted() != MuteState::ForceMuted) {
|
||||||
group->setMuted((group->muted() == MuteState::Active)
|
group->setMuted((group->muted() == MuteState::Muted)
|
||||||
? MuteState::Muted
|
? MuteState::Active
|
||||||
: MuteState::Active);
|
: MuteState::Muted);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -212,7 +212,9 @@ void TopBar::initControls() {
|
||||||
_call ? mapToState(_call->muted()) : _groupCall->muted());
|
_call ? mapToState(_call->muted()) : _groupCall->muted());
|
||||||
auto muted = _call
|
auto muted = _call
|
||||||
? _call->mutedValue() | rpl::map(mapToState)
|
? _call->mutedValue() | rpl::map(mapToState)
|
||||||
: _groupCall->mutedValue();
|
: (_groupCall->mutedValue()
|
||||||
|
| MapPushToTalkToActive()
|
||||||
|
| rpl::distinct_until_changed());
|
||||||
std::move(
|
std::move(
|
||||||
muted
|
muted
|
||||||
) | rpl::start_with_next([=](MuteState state) {
|
) | rpl::start_with_next([=](MuteState state) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue