From 11525a1e50781e06f2ce5bae4507f40fee231990 Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 2 May 2017 14:56:39 +0300 Subject: [PATCH] Add RateCallBox for calls feedback collection. --- Telegram/Resources/icons/call_rating.png | Bin 0 -> 666 bytes Telegram/Resources/icons/call_rating@2x.png | Bin 0 -> 1488 bytes .../Resources/icons/call_rating_filled.png | Bin 0 -> 560 bytes .../Resources/icons/call_rating_filled@2x.png | Bin 0 -> 1127 bytes Telegram/Resources/langs/lang.strings | 3 + Telegram/SourceFiles/boxes/rate_call_box.cpp | 136 ++++++++++++++++++ Telegram/SourceFiles/boxes/rate_call_box.h | 65 +++++++++ Telegram/SourceFiles/boxes/report_box.cpp | 4 +- Telegram/SourceFiles/boxes/report_box.h | 2 +- Telegram/SourceFiles/calls/calls.style | 23 +++ Telegram/SourceFiles/calls/calls_call.cpp | 4 + Telegram/SourceFiles/calls/calls_instance.cpp | 2 + Telegram/gyp/telegram_sources.txt | 2 + 13 files changed, 238 insertions(+), 3 deletions(-) create mode 100644 Telegram/Resources/icons/call_rating.png create mode 100644 Telegram/Resources/icons/call_rating@2x.png create mode 100644 Telegram/Resources/icons/call_rating_filled.png create mode 100644 Telegram/Resources/icons/call_rating_filled@2x.png create mode 100644 Telegram/SourceFiles/boxes/rate_call_box.cpp create mode 100644 Telegram/SourceFiles/boxes/rate_call_box.h diff --git a/Telegram/Resources/icons/call_rating.png b/Telegram/Resources/icons/call_rating.png new file mode 100644 index 0000000000000000000000000000000000000000..6e0fdd9aa4eb013634f274cea31fdeb402bb24e6 GIT binary patch literal 666 zcmV;L0%iS)P)c+KV9`+oPnH&46*KzyNoeC6if02c!!5(%iPdNBmuELBx` zkgBS#YW!O65+{?10GLcBp9>HUhxuCJaM%@qt2{t=YRWs>C6)02ojK0cBp%jNRf09OZ!-=%39VzC%Pp%8+>plwN#glsko z!!Q5<>2w-~VZgF1?Du=y+U<5&tyY-LX3j^TX`1bVz1Da>@rEX&wz zHUNNrzYo(iZ5>&b^=2oMB-y5Qb8~~cyE_1YqA1vIw||}h09LD2K|LCcD9iHMXDiDx zN28IbQ>|9dyM&oc=4gC{LgD1i3x&c_ZYGm)_Z9g4eh!C2QRw#e)^YPjqapmm;gEj6 z|MJhU)9Hw!Ua$9EpV#XZzIMC)aqoblC?v`CdhO_4uh%3=MNv)yIO!?Q=kox7=jUff z@4<7(aneZuxm*qauv{)htXM2!KA&T;SfErYiTJ^D$T>xhW3nuZG|EUMLXxyB>tpUfJRT=Wnx@HCt97(#y1uy!EP)d7y=%NuC(pD3R5aoUs@9V^vDfM*p^!4;gPBL@OJ=eMJtM{3i%;_%xK=_N1LR$cB zBn_Y~fHsl_&=x=&NdssLppB#fv<1)xH3M2&TEO9Oz}ngx7>!0+G63M;SK+ufhr@xd zSX*18qT#<5|4B6(4Zep)qoHB|l_k*I+Z$D1ybxE%D=I2591aUA;Q9F(D=I2}eg*XQ z_CjiEDgXe?&d$Q@>?{BPq@<)!tAe<>otc@59*>8&?%&=IJRT2bW@g5_3gS1J!C)ZC zI-O3^?{qpzzrkSmxdyy_^cjst(r+{xNx#G4_?ZU0Ep@Ngi&1^j@_v=+>1kMBUytf~y-X>9AeYNUmtJRQ zC)Cu`@H9t@Ps@a17@U}x;FVc07{vPe`gq-`BewebdJG1GJZ%#b6UZ=(^iP4lzCOWv z>+kQUmb{przP`S%^2F}=?a3Dv72(#_ z7H{tT{e3JgE&Wr@KNF%*D0pvfh=@L)4{K{{zb*ON+FJDae7rg5=H^hLP{hI;o2Y?- z0l_-#>FJR?`JSF0!90V5gHmwEE>5r4z;s8lMYOkUa# zB3D;e@bvUV&UbfrW9Ho1*&)Z_a2T$xu43kV4@n)pxVRv{SV>7q%zVYg#f0zT;zClb zAoUU`FE1xz&(F^#<2^e&BfRD1<%zol>gwvq@y5o6WW1Z3o1$|_0Z9#LY-}XQpBca~ z3~(F=9LE8}FdxP`olbJx)YKH4ND)X@PS@Ahq*PTZRm8aF=4L!OIU%v9r>EH5+#E5! zu&|KCUSD4)<~^Xgx|)b|xm*!r>~{P67disF-Hz4O)uPuPA0LyrNHJ6m;5d#5oSK^A zjVTlgG@H$WgfA~I@$&Lg&~G-I1@HG$Q&VJ|p zN~IE&N+nt>7QwjJ>*Z~qwYRsEv4w?5Ub_Ld0D&(BAeWpR0VS&-P$(h{;PE4ZFz zSzKIP6vQttFC)vcn3tDF`a+>lVi~})ED?8jc*xrbd45CD=FvxKnzP!Bfc;0f4j*cdd0V^vjf}{}gsCZ7~pohdE#6y7wU96sRW`Za1Eu zp5pNEFv?^y$&!Cd=3Br zyWOr91XgLSRtqVmNGZj3yIpAx0Km#6n9XKD2mwL}IF3_w8h|R)f*|1Wc*LttrxOZ- zP&EtB51LFS_)*j8^y>hkC@KL&QS^5K6h%Q*RdF;Lm4aV29*5msHle0zcsLxM4!+;-QPZ^7oB~;vF$_cQ;9(e| zEX!P{fa_D7=Q+f2%wq)rfH;mJ&vPy>_g!FF7B|3PFyQtAaHL6+B&3vbmw-}=k|e#Z z1cqS%A*9rwrYWRpTIwf+fMFP1tLFmvn9`ysV7Xj^uIr%dIxH3oD2n3ln0tDdrp;#a zp57n`u-omHJe^JlgCKbKZMWOkTt>1iBV!DcBtgrv9!_Xk7A8r8j4|G$c;8@}CVHOt y)PqA11oS))P1AhnE!~D+t$+K!;0NHp0Qe0f=zqUy{HwnJ00003JvB82;bV_Yo84?Co3vpGgYT+s>a4p%F;l}?#=pU#+aN#yr1-5cu=BkBY zn-Ui)e$dB|q;tQE2Yq>7UvtvqoT0qnti;+5dV#RUKW?CtH*iU0tA04P2LLBLwAhP7G^ zCnqPVWB>r9b_(q8?*q^C!1Fx#d_Gz+0DuB@jYfmd&(GLYHk(C_MnkI$l%I5admI0& zot>TE10az|v;jyY62Ak0-EMCyzNy8^Ns@4WeqIp(8X%~Vkr6N$3~gg;YYP~L zk?q4U44j^x!sX>9l*{F|@%i~lEOXb};faX}&}y~da5!LLVWF)!qtOUPqY(@S1B{Q4 z6ASj0USD6KTrNYYRDx2e^uLhq@9*L1=?Pw5Ub^~y*&=$q9#2kA@a^qQb_=UPH#awE zFc`?J0Tzn|Z*OmD*CbnacXv2FJxz8I)M~XDjYetL)>YAH6t!CI;C6vvFo^YfopzmV zs@Lln3U281zP_eb{MFSJ>U6q(iti5q03gS47z%~Hb*0y@BuT-Z0Gh+&@t`P* z120|_Mf7+)L^2Zv006kWyo}jwc3{P4vsqkPS|V9ISpWclCX-3legAir$z;%EGLbHx z{1c&kJ`X(4lePt(=OLfZ6ZZumOmud3miWPt=-A@z>1!NdTeQUs1Z+)9erBdi} zxjK5dTrNzdQeA!QcDwoj`2GHlfh&~?9vvOY`U-^OI6OQ&{PKZ|-|tr+fLJWn7PQf5 zU^pB`K@h&}CkO(D!(nVR8g0I@SWI02SeC_7sq|OKWHO0Pr?YQwr_+haWb!ZXa=A?M z1#15$4u_)^u2?Lh&*vlhhL>eo^!a>PEEZeyI2;c305~`}z(%8i=jZ1=wY%IQ2m+p+ zouMd-xVyVc#FNOEqAM#a@bU2h4-XIhTFKJf+#CP^WHOn)y{LXFs|F3f7N;G6wuS&` t2cWGX0NMd)YY2dL0NNS?pdEm={sHw7H$1RIcpLx#002ovPDHLkV1f*H0Q>*| literal 0 HcmV?d00001 diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 871c9b2e4..084df253e 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -1160,6 +1160,9 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org "lng_call_duration_info" = "{time}, {duration}"; "lng_call_type_and_duration" = "{type} ({duration})"; +"lng_call_rate_label" = "Please rate the quality of your call"; +"lng_call_rate_comment" = "Comment (optional)"; + // Not used "lng_topbar_info" = "Info"; diff --git a/Telegram/SourceFiles/boxes/rate_call_box.cpp b/Telegram/SourceFiles/boxes/rate_call_box.cpp new file mode 100644 index 000000000..ac3021cc0 --- /dev/null +++ b/Telegram/SourceFiles/boxes/rate_call_box.cpp @@ -0,0 +1,136 @@ +/* +This file is part of Telegram Desktop, +the official desktop version of Telegram messaging app, see https://telegram.org + +Telegram Desktop is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +It is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +In addition, as a special exception, the copyright holders give permission +to link the code of portions of this program with the OpenSSL library. + +Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE +Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org +*/ +#include "boxes/rate_call_box.h" + +#include "lang.h" +#include "styles/style_boxes.h" +#include "styles/style_calls.h" +#include "boxes/confirm_box.h" +#include "ui/widgets/labels.h" +#include "ui/widgets/buttons.h" +#include "ui/widgets/input_fields.h" +#include "mainwindow.h" +#include "mainwidget.h" + +namespace { + +constexpr auto kMaxRating = 5; + +} // namespace + +RateCallBox::RateCallBox(QWidget*, uint64 callId, uint64 callAccessHash) +: _callId(callId) +, _callAccessHash(callAccessHash) +, _label(this, lang(lng_call_rate_label), Ui::FlatLabel::InitType::Simple, st::boxLabel) { +} + +void RateCallBox::prepare() { + addButton(lang(lng_cancel), [this] { closeBox(); }); + + for (auto i = 0; i < kMaxRating; ++i) { + _stars.push_back(object_ptr(this, st::callRatingStar)); + _stars.back()->setClickedCallback([this, value = i + 1] { ratingChanged(value); }); + _stars.back()->show(); + } + + updateMaxHeight(); +} + +void RateCallBox::resizeEvent(QResizeEvent *e) { + BoxContent::resizeEvent(e); + + _label->moveToLeft(st::callRatingPadding.left(), st::callRatingPadding.top()); + auto starLeft = st::callRatingPadding.left() + st::callRatingStarLeft; + auto starTop = _label->bottomNoMargins() + st::callRatingStarTop; + for (auto &star : _stars) { + star->moveToLeft(starLeft, starTop); + starLeft += star->width(); + } + if (_comment) { + _comment->moveToLeft(st::callRatingPadding.left(), _stars.back()->bottomNoMargins() + st::callRatingCommentTop); + } +} + +void RateCallBox::ratingChanged(int value) { + Expects(value > 0 && value <= kMaxRating); + if (!_rating) { + clearButtons(); + addButton(lang(lng_send_button), [this] { onSend(); }); + addButton(lang(lng_cancel), [this] { closeBox(); }); + } + _rating = value; + + for (auto i = 0; i < kMaxRating; ++i) { + _stars[i]->setIconOverride((i < value) ? &st::callRatingStarFilled : nullptr); + _stars[i]->setRippleColorOverride((i < value) ? &st::lightButtonBgOver : nullptr); + } + if (value < kMaxRating) { + if (!_comment) { + _comment.create(this, st::callRatingComment, lang(lng_call_rate_comment)); + _comment->show(); + _comment->setCtrlEnterSubmit(Ui::CtrlEnterSubmit::Both); + _comment->setMaxLength(MaxPhotoCaption); + _comment->resize(width() - (st::callRatingPadding.left() + st::callRatingPadding.right()), _comment->height()); + + updateMaxHeight(); + connect(_comment, SIGNAL(resized()), this, SLOT(onCommentResized())); + connect(_comment, SIGNAL(submitted(bool)), this, SLOT(onSend())); + connect(_comment, SIGNAL(cancelled()), this, SLOT(onClose())); + } + _comment->setFocusFast(); + } else if (_comment) { + _comment.destroy(); + updateMaxHeight(); + } +} + +void RateCallBox::setInnerFocus() { + if (_comment) { + _comment->setFocusFast(); + } else { + setFocus(); + } +} + +void RateCallBox::onCommentResized() { + updateMaxHeight(); + update(); +} + +void RateCallBox::onSend() { + Expects(_rating > 0 && _rating <= kMaxRating); + if (_requestId) { + return; + } + auto comment = _comment ? _comment->getLastText().trimmed() : QString(); + _requestId = request(MTPphone_SetCallRating(MTP_inputPhoneCall(MTP_long(_callId), MTP_long(_callAccessHash)), MTP_int(_rating), MTP_string(comment))).done([this](const MTPUpdates &updates) { + App::main()->sentUpdatesReceived(updates); + closeBox(); + }).fail([this](const RPCError &error) { closeBox(); }).send(); +} + +void RateCallBox::updateMaxHeight() { + auto newHeight = st::callRatingPadding.top() + _label->heightNoMargins() + st::callRatingStarTop + _stars.back()->heightNoMargins() + st::callRatingPadding.bottom(); + if (_comment) { + newHeight += st::callRatingCommentTop + _comment->height(); + } + setDimensions(st::boxWidth, newHeight); +} diff --git a/Telegram/SourceFiles/boxes/rate_call_box.h b/Telegram/SourceFiles/boxes/rate_call_box.h new file mode 100644 index 000000000..679ae044d --- /dev/null +++ b/Telegram/SourceFiles/boxes/rate_call_box.h @@ -0,0 +1,65 @@ +/* +This file is part of Telegram Desktop, +the official desktop version of Telegram messaging app, see https://telegram.org + +Telegram Desktop is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +It is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +In addition, as a special exception, the copyright holders give permission +to link the code of portions of this program with the OpenSSL library. + +Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE +Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org +*/ +#pragma once + +#include "boxes/abstract_box.h" +#include "mtproto/sender.h" + +namespace Ui { +class InputArea; +class FlatLabel; +class IconButton; +} // namespace Ui + +class RateCallBox : public BoxContent, private MTP::Sender { + Q_OBJECT + +public: + RateCallBox(QWidget*, uint64 callId, uint64 callAccessHash); + +private slots: + void onSend(); + void onCommentResized(); + void onClose() { + closeBox(); + } + +protected: + void prepare() override; + void setInnerFocus() override; + + void resizeEvent(QResizeEvent *e) override; + +private: + void updateMaxHeight(); + void ratingChanged(int value); + + uint64 _callId = 0; + uint64 _callAccessHash = 0; + int _rating = 0; + + object_ptr _label; + std::vector> _stars; + object_ptr _comment = { nullptr }; + + mtpRequestId _requestId = 0; + +}; diff --git a/Telegram/SourceFiles/boxes/report_box.cpp b/Telegram/SourceFiles/boxes/report_box.cpp index 8f7d45625..b8eb15f1e 100644 --- a/Telegram/SourceFiles/boxes/report_box.cpp +++ b/Telegram/SourceFiles/boxes/report_box.cpp @@ -71,7 +71,7 @@ void ReportBox::reasonChanged(Reason reason) { _reasonOtherText->resize(width() - (st::boxPadding.left() + st::boxOptionListPadding.left() + st::boxPadding.right()), _reasonOtherText->height()); updateMaxHeight(); - connect(_reasonOtherText, SIGNAL(resized()), this, SLOT(onDescriptionResized())); + connect(_reasonOtherText, SIGNAL(resized()), this, SLOT(onReasonResized())); connect(_reasonOtherText, SIGNAL(submitted(bool)), this, SLOT(onReport())); connect(_reasonOtherText, SIGNAL(cancelled()), this, SLOT(onClose())); } @@ -90,7 +90,7 @@ void ReportBox::setInnerFocus() { } } -void ReportBox::onDescriptionResized() { +void ReportBox::onReasonResized() { updateMaxHeight(); update(); } diff --git a/Telegram/SourceFiles/boxes/report_box.h b/Telegram/SourceFiles/boxes/report_box.h index 7f224a737..9d588179a 100644 --- a/Telegram/SourceFiles/boxes/report_box.h +++ b/Telegram/SourceFiles/boxes/report_box.h @@ -38,7 +38,7 @@ public: private slots: void onReport(); - void onDescriptionResized(); + void onReasonResized(); void onClose() { closeBox(); } diff --git a/Telegram/SourceFiles/calls/calls.style b/Telegram/SourceFiles/calls/calls.style index e29a08c4e..a3b027629 100644 --- a/Telegram/SourceFiles/calls/calls.style +++ b/Telegram/SourceFiles/calls/calls.style @@ -161,3 +161,26 @@ callReDial: IconButton { rippleAreaPosition: point(0px, 8px); rippleAreaSize: 40px; } + +callRatingPadding: margins(24px, 26px, 24px, 8px); +callRatingStar: IconButton { + width: 36px; + height: 36px; + + icon: icon {{ "call_rating", windowSubTextFg }}; + iconPosition: point(-1px, -1px); + + ripple: RippleAnimation(defaultRippleAnimation) { + color: windowBgOver; + } + rippleAreaPosition: point(0px, 0px); + rippleAreaSize: 36px; +} +callRatingStarFilled: icon {{ "call_rating_filled", lightButtonFg }}; +callRatingStarLeft: -7px; +callRatingStarTop: 6px; +callRatingComment: InputField(defaultInputField) { + textMargins: margins(1px, 26px, 1px, 4px); + heightMax: 135px; +} +callRatingCommentTop: 2px; diff --git a/Telegram/SourceFiles/calls/calls_call.cpp b/Telegram/SourceFiles/calls/calls_call.cpp index 08d2f098e..6c94e154b 100644 --- a/Telegram/SourceFiles/calls/calls_call.cpp +++ b/Telegram/SourceFiles/calls/calls_call.cpp @@ -24,6 +24,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org #include "mainwidget.h" #include "lang.h" #include "boxes/confirm_box.h" +#include "boxes/rate_call_box.h" #include "calls/calls_instance.h" #include "base/openssl_help.h" #include "mtproto/connection.h" @@ -301,6 +302,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.is_need_rating() && _id && _accessHash) { + Ui::show(Box(_id, _accessHash)); + } if (data.has_reason() && data.vreason.type() == mtpc_phoneCallDiscardReasonDisconnect) { LOG(("Call Info: Discarded with DISCONNECT reason.")); } diff --git a/Telegram/SourceFiles/calls/calls_instance.cpp b/Telegram/SourceFiles/calls/calls_instance.cpp index 220434176..b453b2d79 100644 --- a/Telegram/SourceFiles/calls/calls_instance.cpp +++ b/Telegram/SourceFiles/calls/calls_instance.cpp @@ -29,6 +29,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org #include "calls/calls_call.h" #include "calls/calls_panel.h" + +#include "boxes/rate_call_box.h" namespace Calls { namespace { diff --git a/Telegram/gyp/telegram_sources.txt b/Telegram/gyp/telegram_sources.txt index 2bf7463b2..fed4836d7 100644 --- a/Telegram/gyp/telegram_sources.txt +++ b/Telegram/gyp/telegram_sources.txt @@ -64,6 +64,8 @@ <(src_loc)/boxes/passcode_box.h <(src_loc)/boxes/photo_crop_box.cpp <(src_loc)/boxes/photo_crop_box.h +<(src_loc)/boxes/rate_call_box.cpp +<(src_loc)/boxes/rate_call_box.h <(src_loc)/boxes/report_box.cpp <(src_loc)/boxes/report_box.h <(src_loc)/boxes/self_destruction_box.cpp