mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Fixed crash on incoming peer calls.
This commit is contained in:
parent
6ae15ff264
commit
6f3dbc4305
5 changed files with 71 additions and 45 deletions
|
@ -259,7 +259,7 @@ private:
|
||||||
const not_null<UserData*> _user;
|
const not_null<UserData*> _user;
|
||||||
MTP::Sender _api;
|
MTP::Sender _api;
|
||||||
Type _type = Type::Outgoing;
|
Type _type = Type::Outgoing;
|
||||||
rpl::variable<State> _state = State::WaitingUserConfirmation;
|
rpl::variable<State> _state = State::Starting;
|
||||||
rpl::variable<RemoteAudioState> _remoteAudioState =
|
rpl::variable<RemoteAudioState> _remoteAudioState =
|
||||||
RemoteAudioState::Active;
|
RemoteAudioState::Active;
|
||||||
rpl::variable<Webrtc::VideoState> _remoteVideoState;
|
rpl::variable<Webrtc::VideoState> _remoteVideoState;
|
||||||
|
|
|
@ -324,31 +324,52 @@ void Instance::destroyCall(not_null<Call*> call) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Instance::createCall(not_null<UserData*> user, Call::Type type, bool video) {
|
void Instance::createCall(
|
||||||
auto call = std::make_unique<Call>(_delegate.get(), user, type, video);
|
not_null<UserData*> user,
|
||||||
const auto raw = call.get();
|
Call::Type type,
|
||||||
|
bool isVideo) {
|
||||||
|
struct Performer final {
|
||||||
|
explicit Performer(Fn<void(bool, bool, const Performer &)> callback)
|
||||||
|
: callback(std::move(callback)) {
|
||||||
|
}
|
||||||
|
Fn<void(bool, bool, const Performer &)> callback;
|
||||||
|
};
|
||||||
|
const auto performer = Performer([=](
|
||||||
|
bool video,
|
||||||
|
bool isConfirmed,
|
||||||
|
const Performer &repeater) {
|
||||||
|
const auto delegate = _delegate.get();
|
||||||
|
auto call = std::make_unique<Call>(delegate, user, type, video);
|
||||||
|
if (isConfirmed) {
|
||||||
|
call->applyUserConfirmation();
|
||||||
|
}
|
||||||
|
const auto raw = call.get();
|
||||||
|
|
||||||
user->session().account().sessionChanges(
|
user->session().account().sessionChanges(
|
||||||
) | rpl::start_with_next([=] {
|
) | rpl::start_with_next([=] {
|
||||||
destroyCall(raw);
|
destroyCall(raw);
|
||||||
}, raw->lifetime());
|
}, raw->lifetime());
|
||||||
|
|
||||||
if (_currentCall) {
|
if (_currentCall) {
|
||||||
_currentCallPanel->replaceCall(raw);
|
_currentCallPanel->replaceCall(raw);
|
||||||
std::swap(_currentCall, call);
|
std::swap(_currentCall, call);
|
||||||
call->hangup();
|
call->hangup();
|
||||||
} else {
|
} else {
|
||||||
_currentCallPanel = std::make_unique<Panel>(raw);
|
_currentCallPanel = std::make_unique<Panel>(raw);
|
||||||
_currentCall = std::move(call);
|
_currentCall = std::move(call);
|
||||||
}
|
}
|
||||||
_currentCallPanel->startOutgoingRequests(
|
if (raw->state() == Call::State::WaitingUserConfirmation) {
|
||||||
) | rpl::start_with_next([=](bool video) {
|
_currentCallPanel->startOutgoingRequests(
|
||||||
raw->applyUserConfirmation();
|
) | rpl::start_with_next([=](bool video) {
|
||||||
raw->toggleCameraSharing(video);
|
repeater.callback(video, true, repeater);
|
||||||
refreshServerConfig(&user->session());
|
}, raw->lifetime());
|
||||||
refreshDhConfig();
|
} else {
|
||||||
}, raw->lifetime());
|
refreshServerConfig(&user->session());
|
||||||
_currentCallChanges.fire_copy(raw);
|
refreshDhConfig();
|
||||||
|
}
|
||||||
|
_currentCallChanges.fire_copy(raw);
|
||||||
|
});
|
||||||
|
performer.callback(isVideo, false, performer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Instance::destroyGroupCall(not_null<GroupCall*> call) {
|
void Instance::destroyGroupCall(not_null<GroupCall*> call) {
|
||||||
|
|
|
@ -113,7 +113,7 @@ private:
|
||||||
not_null<Media::Audio::Track*> ensureSoundLoaded(const QString &key);
|
not_null<Media::Audio::Track*> ensureSoundLoaded(const QString &key);
|
||||||
void playSoundOnce(const QString &key);
|
void playSoundOnce(const QString &key);
|
||||||
|
|
||||||
void createCall(not_null<UserData*> user, CallType type, bool video);
|
void createCall(not_null<UserData*> user, CallType type, bool isVideo);
|
||||||
void destroyCall(not_null<Call*> call);
|
void destroyCall(not_null<Call*> call);
|
||||||
|
|
||||||
void createGroupCall(
|
void createGroupCall(
|
||||||
|
|
|
@ -80,9 +80,6 @@ Panel::Panel(not_null<Call*> call)
|
||||||
st::callScreencastOn,
|
st::callScreencastOn,
|
||||||
&st::callScreencastOff))
|
&st::callScreencastOff))
|
||||||
, _camera(widget(), st::callCameraMute, &st::callCameraUnmute)
|
, _camera(widget(), st::callCameraMute, &st::callCameraUnmute)
|
||||||
, _startVideo(
|
|
||||||
widget(),
|
|
||||||
object_ptr<Ui::CallButton>(widget(), st::callStartVideo))
|
|
||||||
, _mute(
|
, _mute(
|
||||||
widget(),
|
widget(),
|
||||||
object_ptr<Ui::CallButton>(
|
object_ptr<Ui::CallButton>(
|
||||||
|
@ -281,6 +278,7 @@ void Panel::initControls() {
|
||||||
} else if (_call->isIncomingWaiting()) {
|
} else if (_call->isIncomingWaiting()) {
|
||||||
_call->answer();
|
_call->answer();
|
||||||
} else if (state == State::WaitingUserConfirmation) {
|
} else if (state == State::WaitingUserConfirmation) {
|
||||||
|
_startOutgoingRequests.fire(false);
|
||||||
} else {
|
} else {
|
||||||
_call->hangup();
|
_call->hangup();
|
||||||
}
|
}
|
||||||
|
@ -292,7 +290,6 @@ void Panel::initControls() {
|
||||||
};
|
};
|
||||||
_decline->entity()->setClickedCallback(hangupCallback);
|
_decline->entity()->setClickedCallback(hangupCallback);
|
||||||
_cancel->entity()->setClickedCallback(hangupCallback);
|
_cancel->entity()->setClickedCallback(hangupCallback);
|
||||||
_startVideo->entity()->setText(tr::lng_call_start_video());
|
|
||||||
|
|
||||||
reinitWithCall(_call);
|
reinitWithCall(_call);
|
||||||
|
|
||||||
|
@ -334,14 +331,10 @@ rpl::lifetime &Panel::chooseSourceInstanceLifetime() {
|
||||||
}
|
}
|
||||||
|
|
||||||
rpl::producer<bool> Panel::startOutgoingRequests() const {
|
rpl::producer<bool> Panel::startOutgoingRequests() const {
|
||||||
const auto filter = [=] {
|
return _startOutgoingRequests.events(
|
||||||
|
) | rpl::filter([=] {
|
||||||
return _call && (_call->state() == State::WaitingUserConfirmation);
|
return _call && (_call->state() == State::WaitingUserConfirmation);
|
||||||
};
|
});
|
||||||
return rpl::merge(
|
|
||||||
_startVideo->entity()->clicks(
|
|
||||||
) | rpl::filter(filter) | rpl::map_to(true),
|
|
||||||
_answerHangupRedial->clicks(
|
|
||||||
) | rpl::filter(filter) | rpl::map_to(false));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panel::chooseSourceAccepted(
|
void Panel::chooseSourceAccepted(
|
||||||
|
@ -478,7 +471,9 @@ void Panel::reinitWithCall(Call *call) {
|
||||||
|
|
||||||
rpl::combine(
|
rpl::combine(
|
||||||
_call->stateValue(),
|
_call->stateValue(),
|
||||||
_call->videoOutgoing()->renderNextFrame()
|
rpl::single(
|
||||||
|
rpl::empty_value()
|
||||||
|
) | rpl::then(_call->videoOutgoing()->renderNextFrame())
|
||||||
) | rpl::start_with_next([=](State state, auto) {
|
) | rpl::start_with_next([=](State state, auto) {
|
||||||
if (state != State::Ended
|
if (state != State::Ended
|
||||||
&& state != State::EndedByOtherDevice
|
&& state != State::EndedByOtherDevice
|
||||||
|
@ -523,7 +518,9 @@ void Panel::reinitWithCall(Call *call) {
|
||||||
_decline->raise();
|
_decline->raise();
|
||||||
_cancel->raise();
|
_cancel->raise();
|
||||||
_camera->raise();
|
_camera->raise();
|
||||||
_startVideo->raise();
|
if (_startVideo) {
|
||||||
|
_startVideo->raise();
|
||||||
|
}
|
||||||
_mute->raise();
|
_mute->raise();
|
||||||
|
|
||||||
_powerSaveBlocker = std::make_unique<base::PowerSaveBlocker>(
|
_powerSaveBlocker = std::make_unique<base::PowerSaveBlocker>(
|
||||||
|
@ -794,7 +791,7 @@ void Panel::updateHangupGeometry() {
|
||||||
_camera->moveToLeft(
|
_camera->moveToLeft(
|
||||||
hangupRight - _mute->width() + _screencast->width(),
|
hangupRight - _mute->width() + _screencast->width(),
|
||||||
_buttonsTop);
|
_buttonsTop);
|
||||||
if (_startVideo->toggled()) {
|
if (_startVideo) {
|
||||||
_startVideo->moveToLeft(_camera->x(), _camera->y());
|
_startVideo->moveToLeft(_camera->x(), _camera->y());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -849,12 +846,18 @@ void Panel::stateChanged(State state) {
|
||||||
if (isBusy) {
|
if (isBusy) {
|
||||||
_powerSaveBlocker = nullptr;
|
_powerSaveBlocker = nullptr;
|
||||||
}
|
}
|
||||||
if (_startVideo->toggled() && !isWaitingUser) {
|
if (_startVideo && !isWaitingUser) {
|
||||||
_startVideo->toggle(false, anim::type::instant);
|
_startVideo = nullptr;
|
||||||
} else if (!_startVideo->toggled() && isWaitingUser) {
|
} else if (!_startVideo && isWaitingUser) {
|
||||||
_startVideo->toggle(true, anim::type::instant);
|
_startVideo = base::make_unique_q<Ui::CallButton>(
|
||||||
|
widget(),
|
||||||
|
st::callStartVideo);
|
||||||
|
_startVideo->setText(tr::lng_call_start_video());
|
||||||
|
_startVideo->clicks() | rpl::map_to(true) | rpl::start_to_stream(
|
||||||
|
_startOutgoingRequests,
|
||||||
|
_startVideo->lifetime());
|
||||||
}
|
}
|
||||||
_camera->setVisible(!_startVideo->toggled());
|
_camera->setVisible(!_startVideo);
|
||||||
|
|
||||||
const auto toggleButton = [&](auto &&button, bool visible) {
|
const auto toggleButton = [&](auto &&button, bool visible) {
|
||||||
button->toggle(
|
button->toggle(
|
||||||
|
|
|
@ -152,7 +152,7 @@ private:
|
||||||
Ui::Animations::Simple _hangupShownProgress;
|
Ui::Animations::Simple _hangupShownProgress;
|
||||||
object_ptr<Ui::FadeWrap<Ui::CallButton>> _screencast;
|
object_ptr<Ui::FadeWrap<Ui::CallButton>> _screencast;
|
||||||
object_ptr<Ui::CallButton> _camera;
|
object_ptr<Ui::CallButton> _camera;
|
||||||
object_ptr<Ui::FadeWrap<Ui::CallButton>> _startVideo;
|
base::unique_qptr<Ui::CallButton> _startVideo;
|
||||||
object_ptr<Ui::FadeWrap<Ui::CallButton>> _mute;
|
object_ptr<Ui::FadeWrap<Ui::CallButton>> _mute;
|
||||||
object_ptr<Ui::FlatLabel> _name;
|
object_ptr<Ui::FlatLabel> _name;
|
||||||
object_ptr<Ui::FlatLabel> _status;
|
object_ptr<Ui::FlatLabel> _status;
|
||||||
|
@ -167,6 +167,8 @@ private:
|
||||||
base::Timer _updateDurationTimer;
|
base::Timer _updateDurationTimer;
|
||||||
base::Timer _updateOuterRippleTimer;
|
base::Timer _updateOuterRippleTimer;
|
||||||
|
|
||||||
|
rpl::event_stream<bool> _startOutgoingRequests;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Calls
|
} // namespace Calls
|
||||||
|
|
Loading…
Add table
Reference in a new issue