Add labels to call buttons.

This commit is contained in:
John Preston 2020-08-14 14:54:15 +04:00
parent 1b60829da8
commit 1aaf7df54a
8 changed files with 96 additions and 21 deletions

Binary file not shown.

After

(image error) Size: 214 B

Binary file not shown.

After

(image error) Size: 426 B

Binary file not shown.

After

(image error) Size: 912 B

View file

@ -84,15 +84,15 @@ callFingerprintTop: 11px;
callFingerprintSkip: 3px;
callFingerprintBottom: -16px;
callTooltipMutedIcon: icon{{ "calls_mute_tooltip", toastFg }};
callTooltipMutedIconPosition: point(8px, 4px);
callTooltipPadding: margins(41px, 6px, 15px, 7px);
callTooltipMutedIcon: icon{{ "calls_mute_tooltip", videoPlayIconFg }};
callTooltipMutedIconPosition: point(10px, 5px);
callTooltipPadding: margins(41px, 7px, 15px, 8px);
callButton: IconButton {
width: 68px;
height: 68px;
height: 79px;
iconPosition: point(-1px, -1px);
iconPosition: point(-1px, 16px);
rippleAreaPosition: point(12px, 12px);
rippleAreaSize: 44px;
@ -100,6 +100,11 @@ callButton: IconButton {
}
callButtonLabel: FlatLabel(defaultFlatLabel) {
textFg: callNameFg;
style: TextStyle(defaultTextStyle) {
font: font(11px);
linkFont: font(11px);
linkFontOver: font(11px underline);
}
}
callAnswer: CallButton {
@ -128,7 +133,7 @@ callHangup: CallButton {
}
callCancel: CallButton {
button: IconButton(callButton) {
icon: icon {{ "box_button_close", callIconFgActive }};
icon: icon {{ "call_cancel", callIconFgActive }};
ripple: RippleAnimation(defaultRippleAnimation) {
color: callIconActiveRipple;
}
@ -199,7 +204,12 @@ callStatus: FlatLabel(defaultFlatLabel) {
}
callRemoteAudioMute: FlatLabel(callStatus) {
minWidth: 0px;
textFg: toastFg;
textFg: videoPlayIconFg;
style: TextStyle(defaultTextStyle) {
font: font(12px);
linkFont: font(12px);
linkFontOver: font(12px underline);
}
}
callRemoteAudioMuteSkip: 12px;

View file

@ -60,12 +60,14 @@ constexpr auto kTooltipShowTimeoutMs = 1000;
class Panel::Button final : public Ui::RippleButton {
public:
Button(QWidget *parent, const style::CallButton &stFrom, const style::CallButton *stTo = nullptr);
Button(
QWidget *parent,
const style::CallButton &stFrom,
const style::CallButton *stTo = nullptr);
void setProgress(float64 progress);
void setOuterValue(float64 value);
void setIconOverride(const style::icon *iconOverride);
void setText(rpl::producer<QString> text);
protected:
void paintEvent(QPaintEvent *e) override;
@ -83,7 +85,7 @@ private:
const style::CallButton *_stTo = nullptr;
float64 _progress = 0.;
const style::icon *_iconOverride = nullptr;
object_ptr<Ui::FlatLabel> _label = { nullptr };
QImage _bgMask, _bg;
QPixmap _bgFrom, _bgTo;
@ -94,7 +96,10 @@ private:
};
Panel::Button::Button(QWidget *parent, const style::CallButton &stFrom, const style::CallButton *stTo)
Panel::Button::Button(
QWidget *parent,
const style::CallButton &stFrom,
const style::CallButton *stTo)
: Ui::RippleButton(parent, stFrom.button.ripple)
, _stFrom(&stFrom)
, _stTo(stTo) {
@ -143,9 +148,18 @@ void Panel::Button::setOuterValue(float64 value) {
}
}
void Panel::Button::setIconOverride(const style::icon *iconOverride) {
_iconOverride = iconOverride;
update();
void Panel::Button::setText(rpl::producer<QString> text) {
_label.create(this, std::move(text), _stFrom->label);
_label->show();
rpl::combine(
sizeValue(),
_label->sizeValue()
) | rpl::start_with_next([=](QSize my, QSize label) {
_label->moveToLeft(
(my.width() - label.width()) / 2,
my.height() - label.height(),
my.width());
}, _label->lifetime());
}
void Panel::Button::setProgress(float64 progress) {
@ -201,7 +215,7 @@ void Panel::Button::paintEvent(QPaintEvent *e) {
auto positionFrom = iconPosition(_stFrom);
if (paintFrom) {
const auto icon = _iconOverride ? _iconOverride : &_stFrom->button.icon;
const auto icon = &_stFrom->button.icon;
icon->paint(p, positionFrom, width());
} else {
auto positionTo = iconPosition(_stTo);
@ -282,7 +296,9 @@ Panel::Panel(not_null<Call*> call)
, _name(widget(), st::callName)
, _status(widget(), st::callStatus) {
_decline->setDuration(st::callPanelDuration);
_decline->entity()->setText(tr::lng_call_decline());
_cancel->setDuration(st::callPanelDuration);
_cancel->entity()->setText(tr::lng_call_cancel());
initWindow();
initWidget();
@ -497,11 +513,18 @@ void Panel::reinitWithCall(Call *call) {
_call->mutedValue(
) | rpl::start_with_next([=](bool mute) {
_mute->setProgress(mute ? 1. : 0.);
_mute->setText(mute
? tr::lng_call_unmute_audio()
: tr::lng_call_mute_audio());
}, _callLifetime);
_call->videoOutgoing()->stateValue(
) | rpl::start_with_next([=](Webrtc::VideoState state) {
_camera->setProgress((state == Webrtc::VideoState::Active) ? 0. : 1.);
const auto active = (state == Webrtc::VideoState::Active);
_camera->setProgress(active ? 0. : 1.);
_camera->setText(active
? tr::lng_call_stop_video()
: tr::lng_call_start_video());
}, _callLifetime);
_call->stateValue(
@ -569,7 +592,7 @@ void Panel::createRemoteAudioMute() {
const auto height = _remoteAudioMute->height();
auto hq = PainterHighQualityEnabler(p);
p.setBrush(st::toastBg);
p.setBrush(st::videoPlayIconBg);
p.setPen(Qt::NoPen);
p.drawRoundedRect(_remoteAudioMute->rect(), height / 2, height / 2);
@ -986,12 +1009,34 @@ void Panel::stateChanged(State state) {
_hangupShown = hangupShown;
_hangupShownProgress.start([this] { updateHangupGeometry(); }, _hangupShown ? 0. : 1., _hangupShown ? 1. : 0., st::callPanelDuration, anim::sineInOut);
}
const auto answerHangupRedialState = incomingWaiting
? AnswerHangupRedialState::Answer
: (state == State::Busy)
? AnswerHangupRedialState::Redial
: AnswerHangupRedialState::Hangup;
if (_answerHangupRedialState != answerHangupRedialState) {
_answerHangupRedialState = answerHangupRedialState;
refreshAnswerHangupRedialLabel();
}
if (_fingerprint.empty() && _call->isKeyShaForFingerprintReady()) {
fillFingerprint();
}
}
}
void Panel::refreshAnswerHangupRedialLabel() {
Expects(_answerHangupRedialState.has_value());
_answerHangupRedial->setText([&] {
switch (*_answerHangupRedialState) {
case AnswerHangupRedialState::Answer: return tr::lng_call_accept();
case AnswerHangupRedialState::Hangup: return tr::lng_call_end_call();
case AnswerHangupRedialState::Redial: return tr::lng_call_redial();
}
Unexpected("AnswerHangupRedialState value.");
}());
}
void Panel::fillFingerprint() {
Expects(_call != nullptr);

View file

@ -60,6 +60,11 @@ private:
class Button;
using State = Call::State;
using Type = Call::Type;
enum class AnswerHangupRedialState : uchar {
Answer,
Hangup,
Redial,
};
[[nodiscard]] not_null<Ui::RpWidget*> widget() const;
@ -101,6 +106,7 @@ private:
void refreshOutgoingPreviewInBody(State state);
void toggleFullScreen(bool fullscreen);
void createRemoteAudioMute();
void refreshAnswerHangupRedialLabel();
[[nodiscard]] QRect incomingFrameGeometry() const;
[[nodiscard]] QRect outgoingFrameGeometry() const;
@ -124,6 +130,7 @@ private:
object_ptr<Ui::FadeWrap<Button>> _cancel;
bool _hangupShown = false;
bool _outgoingPreviewInBody = false;
std::optional<AnswerHangupRedialState> _answerHangupRedialState;
Ui::Animations::Simple _hangupShownProgress;
object_ptr<Button> _camera;
object_ptr<Button> _mute;

View file

@ -107,6 +107,19 @@ void WrapInvokeAfter(
}
}
[[nodiscard]] bool ConstTimeIsDifferent(
const void *a,
const void *b,
size_t size) {
auto ca = reinterpret_cast<const char*>(a);
auto cb = reinterpret_cast<const char*>(b);
volatile auto different = false;
for (const auto ce = ca + size; ca != ce; ++ca, ++cb) {
different |= (*ca != *cb);
}
return different;
}
} // namespace
SessionPrivate::SessionPrivate(
@ -1247,7 +1260,7 @@ void SessionPrivate::handleReceived() {
auto sha1ForMsgKeyCheck = hashSha1(decryptedInts, hashedDataLength);
constexpr auto kMsgKeyShift_oldmtp = 4U;
if (memcmp(&msgKey, sha1ForMsgKeyCheck.data() + kMsgKeyShift_oldmtp, sizeof(msgKey)) != 0) {
if (ConstTimeIsDifferent(&msgKey, sha1ForMsgKeyCheck.data() + kMsgKeyShift_oldmtp, sizeof(msgKey))) {
LOG(("TCP Error: bad SHA1 hash after aesDecrypt in message."));
TCP_LOG(("TCP Error: bad message %1").arg(Logs::mb(encryptedInts, encryptedBytesCount).str()));
@ -1267,7 +1280,7 @@ void SessionPrivate::handleReceived() {
SHA256_Final(sha256Buffer.data(), &msgKeyLargeContext);
constexpr auto kMsgKeyShift = 8U;
if (memcmp(&msgKey, sha256Buffer.data() + kMsgKeyShift, sizeof(msgKey)) != 0) {
if (ConstTimeIsDifferent(&msgKey, sha256Buffer.data() + kMsgKeyShift, sizeof(msgKey))) {
LOG(("TCP Error: bad SHA256 hash after aesDecrypt in message"));
TCP_LOG(("TCP Error: bad message %1").arg(Logs::mb(encryptedInts, encryptedBytesCount).str()));

@ -1 +1 @@
Subproject commit 2850efa0015dc4e6bbd541c0a072497477d75940
Subproject commit 160c1046c18bcf91fc212d9ea042889437189bac