From d5ff728da6216d1978f5a8f65b1698679f709e7e Mon Sep 17 00:00:00 2001 From: John Preston Date: Sat, 29 Apr 2017 19:25:33 +0300 Subject: [PATCH] Show privacy / incompatibility errors in calls. --- Telegram/Resources/langs/lang.strings | 7 +++- Telegram/SourceFiles/calls/calls_call.cpp | 40 ++++++++++++++++--- Telegram/SourceFiles/calls/calls_call.h | 3 ++ Telegram/SourceFiles/calls/calls_instance.cpp | 9 +++++ 4 files changed, 52 insertions(+), 7 deletions(-) diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 4f69ceed15..871c9b2e43 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -1136,12 +1136,17 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org "lng_call_status_failed" = "failed to connect"; "lng_call_status_ringing" = "ringing..."; "lng_call_status_busy" = "line busy"; +"lng_call_fingerprint_tooltip" = "If emoji on {user}'s screen are the same, this call is 100% secure"; + +"lng_call_error_not_available" = "Sorry, {user} doesn't accept calls."; +"lng_call_error_incompatible" = "{user}'s app is using an incompatible protocol. They need to update their app before you can call them."; +"lng_call_error_outdated" = "{user}'s app does not support calls. They need to update their app before you can call them."; "lng_call_bar_info" = "Show call info"; "lng_call_bar_hangup" = "End call"; "lng_call_box_title" = "Calls"; -"lng_call_box_about" = "Your history of Telegram calls will be here."; +"lng_call_box_about" = "You didn't make any calls yet."; "lng_call_box_status_today" = "{time}"; "lng_call_box_status_yesterday" = "Yesterday at {time}"; "lng_call_box_status_date" = "{date} at {time}"; diff --git a/Telegram/SourceFiles/calls/calls_call.cpp b/Telegram/SourceFiles/calls/calls_call.cpp index c1d6e2f5e5..6f6e8ff09d 100644 --- a/Telegram/SourceFiles/calls/calls_call.cpp +++ b/Telegram/SourceFiles/calls/calls_call.cpp @@ -22,6 +22,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org #include "auth_session.h" #include "mainwidget.h" +#include "lang.h" +#include "boxes/confirm_box.h" #include "calls/calls_instance.h" #include "base/openssl_help.h" #include "mtproto/connection.h" @@ -143,7 +145,7 @@ void Call::startOutgoing() { _accessHash = phoneCall.vaccess_hash.v; handleUpdate(call.vphone_call); }).fail([this](const RPCError &error) { - setState(State::Failed); + handleRequestError(error); }).send(); } @@ -156,7 +158,7 @@ void Call::startIncoming() { setState(State::WaitingIncoming); } }).fail([this](const RPCError &error) { - setState(State::Failed); + handleRequestError(error); }).send(); } @@ -179,7 +181,7 @@ void Call::answer() { handleUpdate(call.vphone_call); }).fail([this](const RPCError &error) { - setState(State::Failed); + handleRequestError(error); }).send(); } @@ -283,6 +285,9 @@ bool Call::handleUpdate(const MTPPhoneCall &call) { MTP::send(MTPphone_SaveCallDebug(MTP_inputPhoneCall(MTP_long(_id), MTP_long(_accessHash)), MTP_dataJSON(MTP_string(debugLog)))); } } + if (data.has_reason() && data.vreason.type() == mtpc_phoneCallDiscardReasonDisconnect) { + LOG(("Call Info: Discarded with DISCONNECT reason.")); + } if (data.has_reason() && data.vreason.type() == mtpc_phoneCallDiscardReasonBusy) { setState(State::Busy); } else { @@ -334,7 +339,7 @@ void Call::confirmAcceptedCall(const MTPDphoneCallAccepted &call) { createAndStartController(call.vphone_call.c_phoneCall()); }).fail([this](const RPCError &error) { - setState(State::Failed); + handleRequestError(error); }).send(); } @@ -419,8 +424,9 @@ void Call::handleControllerStateChange(tgvoip::VoIPController *controller, int s } break; case STATE_FAILED: { - DEBUG_LOG(("Call Info: State changed to Failed.")); - setStateQueued(State::Failed); + auto error = controller->GetLastError(); + LOG(("Call Info: State changed to Failed, error: %1.").arg(error)); + setFailedQueued(error); } break; default: LOG(("Call Error: Unexpected state in handleStateChange: %1").arg(state)); @@ -524,6 +530,28 @@ void Call::setStateQueued(State state) { InvokeQueued(this, [this, state] { setState(state); }); } +void Call::setFailedQueued(int error) { + InvokeQueued(this, [this, error] { handleControllerError(error); }); +} + +void Call::handleRequestError(const RPCError &error) { + if (error.type() == qstr("USER_PRIVACY_RESTRICTED")) { + Ui::show(Box(lng_call_error_not_available(lt_user, App::peerName(_user)))); + } else if (error.type() == qstr("PARTICIPANT_VERSION_OUTDATED")) { + Ui::show(Box(lng_call_error_outdated(lt_user, App::peerName(_user)))); + } else if (error.type() == qstr("CALL_PROTOCOL_LAYER_INVALID")) { + Ui::show(Box(lng_call_error_incompatible(lt_user, App::peerName(_user)))); + } + setState(State::Failed); +} + +void Call::handleControllerError(int error) { + if (error == TGVOIP_ERROR_INCOMPATIBLE) { + Ui::show(Box(lng_call_error_incompatible(lt_user, App::peerName(_user)))); + } + setState(State::Failed); +} + Call::~Call() { if (_controller) { DEBUG_LOG(("Call Info: Destroying call controller..")); diff --git a/Telegram/SourceFiles/calls/calls_call.h b/Telegram/SourceFiles/calls/calls_call.h index 8fa59b1d27..cbedd17fec 100644 --- a/Telegram/SourceFiles/calls/calls_call.h +++ b/Telegram/SourceFiles/calls/calls_call.h @@ -107,6 +107,8 @@ public: ~Call(); private: + void handleRequestError(const RPCError &error); + void handleControllerError(int error); void finish(const MTPPhoneCallDiscardReason &reason); void startOutgoing(); void startIncoming(); @@ -124,6 +126,7 @@ private: void startConfirmedCall(const MTPDphoneCall &call); void setState(State state); void setStateQueued(State state); + void setFailedQueued(int error); gsl::not_null _delegate; gsl::not_null _user; diff --git a/Telegram/SourceFiles/calls/calls_instance.cpp b/Telegram/SourceFiles/calls/calls_instance.cpp index 9711db559b..dbdf6d95dc 100644 --- a/Telegram/SourceFiles/calls/calls_instance.cpp +++ b/Telegram/SourceFiles/calls/calls_instance.cpp @@ -22,6 +22,9 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org #include "mtproto/connection.h" #include "auth_session.h" +#include "apiwrap.h" +#include "lang.h" +#include "boxes/confirm_box.h" #include "calls/calls_call.h" #include "calls/calls_panel.h" @@ -39,6 +42,12 @@ void Instance::startOutgoingCall(gsl::not_null user) { _currentCallPanel->showAndActivate(); return; // Already in a call. } + if (user->callsStatus() == UserData::CallsStatus::Private) { + // Request full user once more to refresh the setting in case it was changed. + AuthSession::Current().api().requestFullPeer(user); + Ui::show(Box(lng_call_error_not_available(lt_user, App::peerName(user)))); + return; + } createCall(user, Call::Type::Outgoing); }