Add group calls top bar.

This commit is contained in:
John Preston 2020-11-24 17:40:10 +03:00
parent 8833d3e45b
commit 41591ff2e9
10 changed files with 136 additions and 36 deletions

View file

@ -183,7 +183,6 @@ void GroupCall::checkParticipants() {
}
}
_instance->setSsrcs(std::move(ssrcs));
_instance->setIsMuted(false);
}
void GroupCall::hangup() {
@ -342,9 +341,7 @@ void GroupCall::createAndStartController() {
std::move(descriptor));
const auto raw = _instance.get();
if (_muted.current()) {
raw->setIsMuted(_muted.current());
}
raw->setIsMuted(_muted.current());
//raw->setAudioOutputDuckingEnabled(settings.callAudioDuckingEnabled());
}

View file

@ -53,7 +53,7 @@ public:
return _muted.value();
}
[[nodiscard]] bool joined() const {
return _mySsrc != 0;
return (_state.current() == State::Joined);
}
enum State {
@ -103,7 +103,7 @@ private:
MTP::Sender _api;
rpl::variable<State> _state = State::Creating;
rpl::variable<bool> _muted = false;
rpl::variable<bool> _muted = true;
bool _acceptFields = false;
uint64 _id = 0;

View file

@ -17,6 +17,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "calls/calls_instance.h"
#include "calls/calls_signal_bars.h"
#include "data/data_user.h"
#include "data/data_channel.h"
#include "data/data_changes.h"
#include "main/main_session.h"
#include "boxes/abstract_box.h"
@ -77,10 +78,28 @@ void DebugInfoBox::updateText() {
TopBar::TopBar(
QWidget *parent,
const base::weak_ptr<Call> &call)
: TopBar(parent, call, nullptr) {
}
TopBar::TopBar(
QWidget *parent,
const base::weak_ptr<GroupCall> &call)
: TopBar(parent, nullptr, call) {
}
TopBar::TopBar(
QWidget *parent,
const base::weak_ptr<Call> &call,
const base::weak_ptr<GroupCall> &groupCall)
: RpWidget(parent)
, _call(call)
, _durationLabel(this, st::callBarLabel)
, _signalBars(this, _call.get(), st::callBarSignalBars)
, _groupCall(groupCall)
, _durationLabel(_call
? object_ptr<Ui::LabelSimple>(this, st::callBarLabel)
: object_ptr<Ui::LabelSimple>(nullptr))
, _signalBars(_call
? object_ptr<SignalBars>(this, _call.get(), st::callBarSignalBars)
: object_ptr<SignalBars>(nullptr))
, _fullInfoLabel(this, st::callBarInfoLabel)
, _shortInfoLabel(this, st::callBarInfoLabel)
, _hangupLabel(this, st::callBarLabel, tr::lng_call_bar_hangup(tr::now).toUpper())
@ -95,22 +114,31 @@ void TopBar::initControls() {
_mute->setClickedCallback([=] {
if (const auto call = _call.get()) {
call->setMuted(!call->muted());
} else if (const auto group = _groupCall.get()) {
group->setMuted(!group->muted());
}
});
_call->mutedValue(
auto muted = _call
? _call->mutedValue()
: _groupCall->mutedValue();
std::move(
muted
) | rpl::start_with_next([=](bool muted) {
setMuted(muted);
update();
}, lifetime());
_call->user()->session().changes().peerUpdates(
Data::PeerUpdate::Flag::Name
) | rpl::filter([=](const Data::PeerUpdate &update) {
// _user may change for the same Panel.
return (_call != nullptr) && (update.peer == _call->user());
}) | rpl::start_with_next([=] {
updateInfoLabels();
}, lifetime());
if (const auto call = _call.get()) {
call->user()->session().changes().peerUpdates(
Data::PeerUpdate::Flag::Name
) | rpl::filter([=](const Data::PeerUpdate &update) {
// _user may change for the same Panel.
return (_call != nullptr) && (update.peer == _call->user());
}) | rpl::start_with_next([=] {
updateInfoLabels();
}, lifetime());
}
setInfoLabels();
_info->setClickedCallback([=] {
@ -121,11 +149,15 @@ void TopBar::initControls() {
} else {
Core::App().calls().showInfoPanel(call);
}
} else if (const auto group = _groupCall.get()) {
Core::App().calls().showInfoPanel(group);
}
});
_hangup->setClickedCallback([this] {
if (auto call = _call.get()) {
if (const auto call = _call.get()) {
call->hangup();
} else if (const auto group = _groupCall.get()) {
group->hangup();
}
});
_updateDurationTimer.setCallback([this] { updateDurationText(); });
@ -144,6 +176,11 @@ void TopBar::setInfoLabels() {
const auto shortName = user->firstName;
_fullInfoLabel->setText(fullName.toUpper());
_shortInfoLabel->setText(shortName.toUpper());
} else if (const auto group = _groupCall.get()) {
const auto channel = group->channel();
const auto name = channel->name;
_fullInfoLabel->setText(name.toUpper());
_shortInfoLabel->setText(name.toUpper());
}
}
@ -155,7 +192,7 @@ void TopBar::setMuted(bool mute) {
}
void TopBar::updateDurationText() {
if (!_call) {
if (!_call || !_durationLabel) {
return;
}
auto wasWidth = _durationLabel->width();
@ -181,10 +218,14 @@ void TopBar::updateControlsGeometry() {
auto left = 0;
_mute->moveToLeft(left, 0);
left += _mute->width();
_durationLabel->moveToLeft(left, st::callBarLabelTop);
left += _durationLabel->width() + st::callBarSkip;
_signalBars->moveToLeft(left, (height() - _signalBars->height()) / 2);
left += _signalBars->width() + st::callBarSkip;
if (_durationLabel) {
_durationLabel->moveToLeft(left, st::callBarLabelTop);
left += _durationLabel->width() + st::callBarSkip;
}
if (_signalBars) {
_signalBars->moveToLeft(left, (height() - _signalBars->height()) / 2);
left += _signalBars->width() + st::callBarSkip;
}
auto right = st::callBarRightSkip;
_hangupLabel->moveToRight(right, st::callBarLabelTop);

View file

@ -26,11 +26,13 @@ class Session;
namespace Calls {
class Call;
class GroupCall;
class SignalBars;
class TopBar : public Ui::RpWidget {
public:
TopBar(QWidget *parent, const base::weak_ptr<Call> &call);
TopBar(QWidget *parent, const base::weak_ptr<GroupCall> &call);
~TopBar();
@ -39,6 +41,11 @@ protected:
void paintEvent(QPaintEvent *e) override;
private:
TopBar(
QWidget *parent,
const base::weak_ptr<Call> &call,
const base::weak_ptr<GroupCall> &groupCall);
void initControls();
void updateInfoLabels();
void setInfoLabels();
@ -48,6 +55,7 @@ private:
void setMuted(bool mute);
const base::weak_ptr<Call> _call;
const base::weak_ptr<GroupCall> _groupCall;
bool _muted = false;
object_ptr<Ui::LabelSimple> _durationLabel;

View file

@ -682,10 +682,14 @@ void ChannelData::setCall(const MTPInputGroupCall &call) {
clearCall();
return;
}
if (_call) {
owner().unregisterGroupCall(_call.get());
}
_call = std::make_unique<Data::GroupCall>(
this,
data.vid().v,
data.vaccess_hash().v);
owner().registerGroupCall(_call.get());
session().changes().peerUpdated(this, UpdateFlag::GroupCall);
});
}
@ -694,6 +698,7 @@ void ChannelData::clearCall() {
if (!_call) {
return;
}
owner().unregisterGroupCall(_call.get());
_call = nullptr;
session().changes().peerUpdated(this, UpdateFlag::GroupCall);
}

View file

@ -12,6 +12,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_group_call.h"
#include "main/main_session.h"
#include "ui/chat/group_call_bar.h"
#include "calls/calls_group_call.h"
#include "calls/calls_instance.h"
#include "core/application.h"
namespace HistoryView {
@ -21,12 +24,15 @@ GroupCallTracker::GroupCallTracker(not_null<ChannelData*> channel)
rpl::producer<Ui::GroupCallBarContent> GroupCallTracker::content() const {
const auto channel = _channel;
return channel->session().changes().peerFlagsValue(
channel,
Data::PeerUpdate::Flag::GroupCall
) | rpl::map([=]() -> Ui::GroupCallBarContent {
return rpl::combine(
channel->session().changes().peerFlagsValue(
channel,
Data::PeerUpdate::Flag::GroupCall),
Core::App().calls().currentGroupCallValue()
) | rpl::map([=](const auto&, Calls::GroupCall *current)
-> Ui::GroupCallBarContent {
const auto call = channel->call();
if (!call) {
if (!call || (current && current->channel() == channel)) {
return { .shown = false };
} else if (!call->fullCount() && !call->participantsLoaded()) {
call->requestParticipants();

View file

@ -254,6 +254,10 @@ MainWidget::MainWidget(
) | rpl::start_with_next([=](Calls::Call *call) {
setCurrentCall(call);
}, lifetime());
Core::App().calls().currentGroupCallValue(
) | rpl::start_with_next([=](Calls::GroupCall *call) {
setCurrentGroupCall(call);
}, lifetime());
if (_callTopBar) {
_callTopBar->finishAnimating();
}
@ -942,6 +946,9 @@ void MainWidget::playerHeightUpdated() {
}
void MainWidget::setCurrentCall(Calls::Call *call) {
if (!call && _currentGroupCall) {
return;
}
_currentCallLifetime.destroy();
_currentCall = call;
if (_currentCall) {
@ -959,10 +966,35 @@ void MainWidget::setCurrentCall(Calls::Call *call) {
}
}
void MainWidget::createCallTopBar() {
Expects(_currentCall != nullptr);
void MainWidget::setCurrentGroupCall(Calls::GroupCall *call) {
if (!call && _currentCall) {
return;
}
_currentCallLifetime.destroy();
_currentGroupCall = call;
if (_currentGroupCall) {
_currentGroupCall->stateValue(
) | rpl::start_with_next([=](Calls::GroupCall::State state) {
using State = Calls::GroupCall::State;
if (state == State::Joined) {
createCallTopBar();
} else {
destroyCallTopBar();
}
}, _currentCallLifetime);
} else {
destroyCallTopBar();
}
}
_callTopBar.create(this, object_ptr<Calls::TopBar>(this, _currentCall));
void MainWidget::createCallTopBar() {
Expects(_currentCall != nullptr || _currentGroupCall != nullptr);
_callTopBar.create(
this,
(_currentCall
? object_ptr<Calls::TopBar>(this, _currentCall)
: object_ptr<Calls::TopBar>(this, _currentGroupCall)));
_callTopBar->heightValue(
) | rpl::start_with_next([this](int value) {
callTopBarHeightUpdated(value);
@ -986,7 +1018,7 @@ void MainWidget::destroyCallTopBar() {
}
void MainWidget::callTopBarHeightUpdated(int callTopBarHeight) {
if (!callTopBarHeight && !_currentCall) {
if (!callTopBarHeight && !_currentCall && !_currentGroupCall) {
_callTopBar.destroyDelayed();
}
if (callTopBarHeight != _callTopBarHeight) {

View file

@ -85,6 +85,7 @@ class HistoryHider;
namespace Calls {
class Call;
class GroupCall;
class TopBar;
} // namespace Calls
@ -257,6 +258,7 @@ private:
void playerHeightUpdated();
void setCurrentCall(Calls::Call *call);
void setCurrentGroupCall(Calls::GroupCall *call);
void createCallTopBar();
void destroyCallTopBar();
void callTopBarHeightUpdated(int callTopBarHeight);
@ -350,6 +352,7 @@ private:
std::unique_ptr<Window::ConnectionState> _connecting;
base::weak_ptr<Calls::Call> _currentCall;
base::weak_ptr<Calls::GroupCall> _currentGroupCall;
rpl::lifetime _currentCallLifetime;
object_ptr<Ui::SlideWrap<Calls::TopBar>> _callTopBar = { nullptr };

View file

@ -114,8 +114,12 @@ Instance::Instance()
handleSongUpdate(audioId);
});
Core::App().calls().currentCallValue(
) | rpl::start_with_next([=](Calls::Call *call) {
using namespace rpl::mappers;
rpl::combine(
Core::App().calls().currentCallValue(),
Core::App().calls().currentGroupCallValue(),
_1 || _2
) | rpl::start_with_next([=](bool call) {
if (call) {
pauseOnCall(AudioMsgId::Type::Voice);
pauseOnCall(AudioMsgId::Type::Song);

View file

@ -395,8 +395,12 @@ OverlayWidget::OverlayWidget()
_touchbarFullscreenToggled.events());
#endif // Q_OS_MAC && !OS_OSX
Core::App().calls().currentCallValue(
) | rpl::start_with_next([=](Calls::Call *call) {
using namespace rpl::mappers;
rpl::combine(
Core::App().calls().currentCallValue(),
Core::App().calls().currentGroupCallValue(),
_1 || _2
) | rpl::start_with_next([=](bool call) {
if (!_streamed || videoIsGifOrUserpic()) {
return;
} else if (call) {