Reuse call panel if current call is in Busy state.

This commit is contained in:
John Preston 2017-05-04 15:29:32 +03:00
parent 0a6e012e90
commit 299dc3fc96
6 changed files with 56 additions and 30 deletions

View file

@ -62,8 +62,17 @@ public:
weak_unique_ptr() = default;
weak_unique_ptr(T *value) : _guarded(value ? value->getGuarded() : std::shared_ptr<enable_weak_from_this*>()) {
}
weak_unique_ptr(const std::unique_ptr<T> &value) : _guarded(value ? value->getGuarded() : std::shared_ptr<enable_weak_from_this*>()) {
weak_unique_ptr(const std::unique_ptr<T> &value) : weak_unique_ptr(value.get()) {
}
weak_unique_ptr &operator=(T *value) {
_guarded = value ? value->getGuarded() : std::shared_ptr<enable_weak_from_this*>();
return *this;
}
weak_unique_ptr &operator=(const std::unique_ptr<T> &value) {
return (*this = value.get());
}
T *get() const noexcept {
if (auto shared = _guarded.lock()) {
return static_cast<T*>(*shared);

View file

@ -91,7 +91,7 @@ callMuteRight: 12px;
callNameTop: 15px;
callName: FlatLabel(defaultFlatLabel) {
width: 260px;
maxHeight: 24px;
maxHeight: 30px;
textFg: callNameFg;
align: align(top);
style: TextStyle(defaultTextStyle) {

View file

@ -41,8 +41,7 @@ constexpr auto kServerConfigUpdateTimeoutMs = 24 * 3600 * TimeMs(1000);
Instance::Instance() = default;
void Instance::startOutgoingCall(gsl::not_null<UserData*> user) {
finishCurrentBusyCall();
if (_currentCall) { // Already in a call.
if (alreadyInCall()) { // Already in a call.
_currentCallPanel->showAndActivate();
return;
}
@ -111,8 +110,15 @@ void Instance::destroyCall(gsl::not_null<Call*> call) {
}
void Instance::createCall(gsl::not_null<UserData*> user, Call::Type type) {
_currentCall = std::make_unique<Call>(getCallDelegate(), user, type);
_currentCallPanel = std::make_unique<Panel>(_currentCall.get());
auto call = std::make_unique<Call>(getCallDelegate(), user, type);;
if (_currentCall) {
_currentCallPanel->replaceCall(call.get());
std::swap(_currentCall, call);
call->hangup();
} else {
_currentCallPanel = std::make_unique<Panel>(call.get());
_currentCall = std::move(call);
}
_currentCallChanged.notify(_currentCall.get(), true);
refreshServerConfig();
refreshDhConfig();
@ -259,10 +265,9 @@ void Instance::handleCallUpdate(const MTPPhoneCall &call) {
} else if (user->isSelf()) {
LOG(("API Error: Self found in phoneCallRequested."));
}
finishCurrentBusyCall();
if (_currentCall || !user || user->isSelf()) {
if (alreadyInCall() || !user || user->isSelf()) {
request(MTPphone_DiscardCall(MTP_inputPhoneCall(phoneCall.vid, phoneCall.vaccess_hash), MTP_int(0), MTP_phoneCallDiscardReasonBusy(), MTP_long(0))).send();
} else if (phoneCall.vdate.v + Global::CallRingTimeoutMs() / 1000 < unixtime()) {
} else if (phoneCall.vdate.v + (Global::CallRingTimeoutMs() / 1000) < unixtime()) {
LOG(("Ignoring too old call."));
} else {
createCall(user, Call::Type::Incoming);
@ -273,10 +278,8 @@ void Instance::handleCallUpdate(const MTPPhoneCall &call) {
}
}
void Instance::finishCurrentBusyCall() {
if (_currentCall && _currentCall->state() == Call::State::Busy) {
_currentCall->hangup();
}
bool Instance::alreadyInCall() {
return (_currentCall && _currentCall->state() != Call::State::Busy);
}
Instance::~Instance() = default;

View file

@ -71,7 +71,7 @@ private:
void refreshDhConfig();
void refreshServerConfig();
void finishCurrentBusyCall();
bool alreadyInCall();
void handleCallUpdate(const MTPPhoneCall &call);
DhConfig _dhConfig;

View file

@ -106,7 +106,6 @@ QImage Panel::Button::prepareRippleMask() const {
Panel::Panel(gsl::not_null<Call*> call)
: _call(call)
, _user(call->user())
, _hangup(this, st::callHangup)
, _mute(this, st::callMuteToggle)
, _name(this, st::callName)
, _status(this, st::callStatus) {
@ -124,6 +123,13 @@ void Panel::showAndActivate() {
setFocus();
}
void Panel::replaceCall(gsl::not_null<Call*> call) {
_call = call;
_user = call->user();
reinitControls();
updateControlsGeometry();
}
bool Panel::event(QEvent *e) {
if (e->type() == QEvent::WindowDeactivate) {
if (_call && _call->state() == State::Established) {
@ -138,20 +144,12 @@ void Panel::hideDeactivated() {
}
void Panel::initControls() {
subscribe(_call->stateChanged(), [this](State state) { stateChanged(state); });
if (_call->type() == Type::Incoming) {
_answer.create(this, st::callAnswer);
}
refreshCallbacks();
_mute->setClickedCallback([this] {
_call->setMute(!_call->isMute());
});
subscribe(_call->muteChanged(), [this](bool mute) {
_mute->setIconOverride(mute ? &st::callUnmuteIcon : nullptr);
});
_name->setText(App::peerName(_call->user()));
subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(Notify::PeerUpdate::Flag::NameChanged, [this](const Notify::PeerUpdate &update) {
if (!_call || update.peer != _call->user()) {
return;
@ -159,12 +157,22 @@ void Panel::initControls() {
_name->setText(App::peerName(_call->user()));
updateControlsGeometry();
}));
updateStatusText(_call->state());
_updateDurationTimer.setCallback([this] {
if (_call) {
updateStatusText(_call->state());
}
});
reinitControls();
}
void Panel::reinitControls() {
unsubscribe(_stateChangedSubscription);
_stateChangedSubscription = subscribe(_call->stateChanged(), [this](State state) { stateChanged(state); });
stateChanged(_call->state());
_name->setText(App::peerName(_call->user()));
updateStatusText(_call->state());
}
void Panel::refreshCallbacks() {
@ -459,11 +467,12 @@ void Panel::stateChanged(State state) {
}
buttonsUpdated = true;
};
syncButton(_answer, (state == State::Starting) || (state == State::WaitingIncoming), st::callAnswer);
syncButton(_hangup, (state != State::Busy), st::callHangup);
syncButton(_redial, (state == State::Busy), st::callAnswer);
syncButton(_cancel, (state == State::Busy), st::callCancel);
if (_call) {
syncButton(_answer, (_call->type() == Call::Type::Incoming) && ((state == State::Starting) || (state == State::WaitingIncoming)), st::callAnswer);
syncButton(_hangup, (state != State::Busy), st::callHangup);
syncButton(_redial, (state == State::Busy), st::callAnswer);
syncButton(_cancel, (state == State::Busy), st::callCancel);
}
if (buttonsUpdated) {
refreshCallbacks();
updateControlsGeometry();

View file

@ -38,6 +38,8 @@ public:
void showAndActivate();
void replaceCall(gsl::not_null<Call*> call);
protected:
void paintEvent(QPaintEvent *e) override;
void resizeEvent(QResizeEvent *e) override;
@ -58,6 +60,7 @@ private:
bool tooltipWindowActive() const override;
void initControls();
void reinitControls();
void initLayout();
void initGeometry();
void refreshCallbacks();
@ -89,9 +92,11 @@ private:
QPoint _dragStartMousePosition;
QPoint _dragStartMyPosition;
int _stateChangedSubscription = 0;
class Button;
object_ptr<Ui::IconButton> _close = { nullptr };
object_ptr<Button> _hangup;
object_ptr<Button> _hangup = { nullptr };
object_ptr<Button> _cancel = { nullptr };
object_ptr<Button> _answer = { nullptr };
object_ptr<Button> _redial = { nullptr };