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

View file

@ -53,7 +53,7 @@ public:
return _muted.value(); return _muted.value();
} }
[[nodiscard]] bool joined() const { [[nodiscard]] bool joined() const {
return _mySsrc != 0; return (_state.current() == State::Joined);
} }
enum State { enum State {
@ -103,7 +103,7 @@ private:
MTP::Sender _api; MTP::Sender _api;
rpl::variable<State> _state = State::Creating; rpl::variable<State> _state = State::Creating;
rpl::variable<bool> _muted = false; rpl::variable<bool> _muted = true;
bool _acceptFields = false; bool _acceptFields = false;
uint64 _id = 0; 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_instance.h"
#include "calls/calls_signal_bars.h" #include "calls/calls_signal_bars.h"
#include "data/data_user.h" #include "data/data_user.h"
#include "data/data_channel.h"
#include "data/data_changes.h" #include "data/data_changes.h"
#include "main/main_session.h" #include "main/main_session.h"
#include "boxes/abstract_box.h" #include "boxes/abstract_box.h"
@ -77,10 +78,28 @@ void DebugInfoBox::updateText() {
TopBar::TopBar( TopBar::TopBar(
QWidget *parent, QWidget *parent,
const base::weak_ptr<Call> &call) 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) : RpWidget(parent)
, _call(call) , _call(call)
, _durationLabel(this, st::callBarLabel) , _groupCall(groupCall)
, _signalBars(this, _call.get(), st::callBarSignalBars) , _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) , _fullInfoLabel(this, st::callBarInfoLabel)
, _shortInfoLabel(this, st::callBarInfoLabel) , _shortInfoLabel(this, st::callBarInfoLabel)
, _hangupLabel(this, st::callBarLabel, tr::lng_call_bar_hangup(tr::now).toUpper()) , _hangupLabel(this, st::callBarLabel, tr::lng_call_bar_hangup(tr::now).toUpper())
@ -95,22 +114,31 @@ void TopBar::initControls() {
_mute->setClickedCallback([=] { _mute->setClickedCallback([=] {
if (const auto call = _call.get()) { if (const auto call = _call.get()) {
call->setMuted(!call->muted()); 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) { ) | rpl::start_with_next([=](bool muted) {
setMuted(muted); setMuted(muted);
update(); update();
}, lifetime()); }, lifetime());
_call->user()->session().changes().peerUpdates( if (const auto call = _call.get()) {
Data::PeerUpdate::Flag::Name call->user()->session().changes().peerUpdates(
) | rpl::filter([=](const Data::PeerUpdate &update) { Data::PeerUpdate::Flag::Name
// _user may change for the same Panel. ) | rpl::filter([=](const Data::PeerUpdate &update) {
return (_call != nullptr) && (update.peer == _call->user()); // _user may change for the same Panel.
}) | rpl::start_with_next([=] { return (_call != nullptr) && (update.peer == _call->user());
updateInfoLabels(); }) | rpl::start_with_next([=] {
}, lifetime()); updateInfoLabels();
}, lifetime());
}
setInfoLabels(); setInfoLabels();
_info->setClickedCallback([=] { _info->setClickedCallback([=] {
@ -121,11 +149,15 @@ void TopBar::initControls() {
} else { } else {
Core::App().calls().showInfoPanel(call); Core::App().calls().showInfoPanel(call);
} }
} else if (const auto group = _groupCall.get()) {
Core::App().calls().showInfoPanel(group);
} }
}); });
_hangup->setClickedCallback([this] { _hangup->setClickedCallback([this] {
if (auto call = _call.get()) { if (const auto call = _call.get()) {
call->hangup(); call->hangup();
} else if (const auto group = _groupCall.get()) {
group->hangup();
} }
}); });
_updateDurationTimer.setCallback([this] { updateDurationText(); }); _updateDurationTimer.setCallback([this] { updateDurationText(); });
@ -144,6 +176,11 @@ void TopBar::setInfoLabels() {
const auto shortName = user->firstName; const auto shortName = user->firstName;
_fullInfoLabel->setText(fullName.toUpper()); _fullInfoLabel->setText(fullName.toUpper());
_shortInfoLabel->setText(shortName.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() { void TopBar::updateDurationText() {
if (!_call) { if (!_call || !_durationLabel) {
return; return;
} }
auto wasWidth = _durationLabel->width(); auto wasWidth = _durationLabel->width();
@ -181,10 +218,14 @@ void TopBar::updateControlsGeometry() {
auto left = 0; auto left = 0;
_mute->moveToLeft(left, 0); _mute->moveToLeft(left, 0);
left += _mute->width(); left += _mute->width();
_durationLabel->moveToLeft(left, st::callBarLabelTop); if (_durationLabel) {
left += _durationLabel->width() + st::callBarSkip; _durationLabel->moveToLeft(left, st::callBarLabelTop);
_signalBars->moveToLeft(left, (height() - _signalBars->height()) / 2); left += _durationLabel->width() + st::callBarSkip;
left += _signalBars->width() + st::callBarSkip; }
if (_signalBars) {
_signalBars->moveToLeft(left, (height() - _signalBars->height()) / 2);
left += _signalBars->width() + st::callBarSkip;
}
auto right = st::callBarRightSkip; auto right = st::callBarRightSkip;
_hangupLabel->moveToRight(right, st::callBarLabelTop); _hangupLabel->moveToRight(right, st::callBarLabelTop);

View file

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

View file

@ -682,10 +682,14 @@ void ChannelData::setCall(const MTPInputGroupCall &call) {
clearCall(); clearCall();
return; return;
} }
if (_call) {
owner().unregisterGroupCall(_call.get());
}
_call = std::make_unique<Data::GroupCall>( _call = std::make_unique<Data::GroupCall>(
this, this,
data.vid().v, data.vid().v,
data.vaccess_hash().v); data.vaccess_hash().v);
owner().registerGroupCall(_call.get());
session().changes().peerUpdated(this, UpdateFlag::GroupCall); session().changes().peerUpdated(this, UpdateFlag::GroupCall);
}); });
} }
@ -694,6 +698,7 @@ void ChannelData::clearCall() {
if (!_call) { if (!_call) {
return; return;
} }
owner().unregisterGroupCall(_call.get());
_call = nullptr; _call = nullptr;
session().changes().peerUpdated(this, UpdateFlag::GroupCall); 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 "data/data_group_call.h"
#include "main/main_session.h" #include "main/main_session.h"
#include "ui/chat/group_call_bar.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 { namespace HistoryView {
@ -21,12 +24,15 @@ GroupCallTracker::GroupCallTracker(not_null<ChannelData*> channel)
rpl::producer<Ui::GroupCallBarContent> GroupCallTracker::content() const { rpl::producer<Ui::GroupCallBarContent> GroupCallTracker::content() const {
const auto channel = _channel; const auto channel = _channel;
return channel->session().changes().peerFlagsValue( return rpl::combine(
channel, channel->session().changes().peerFlagsValue(
Data::PeerUpdate::Flag::GroupCall channel,
) | rpl::map([=]() -> Ui::GroupCallBarContent { Data::PeerUpdate::Flag::GroupCall),
Core::App().calls().currentGroupCallValue()
) | rpl::map([=](const auto&, Calls::GroupCall *current)
-> Ui::GroupCallBarContent {
const auto call = channel->call(); const auto call = channel->call();
if (!call) { if (!call || (current && current->channel() == channel)) {
return { .shown = false }; return { .shown = false };
} else if (!call->fullCount() && !call->participantsLoaded()) { } else if (!call->fullCount() && !call->participantsLoaded()) {
call->requestParticipants(); call->requestParticipants();

View file

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

View file

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

View file

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

View file

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