diff --git a/Telegram/Resources/icons/calls_mute_tooltip.png b/Telegram/Resources/icons/calls_mute_tooltip.png new file mode 100644 index 000000000..9581af158 Binary files /dev/null and b/Telegram/Resources/icons/calls_mute_tooltip.png differ diff --git a/Telegram/Resources/icons/calls_mute_tooltip@2x.png b/Telegram/Resources/icons/calls_mute_tooltip@2x.png new file mode 100644 index 000000000..bcc7d385e Binary files /dev/null and b/Telegram/Resources/icons/calls_mute_tooltip@2x.png differ diff --git a/Telegram/Resources/icons/calls_mute_tooltip@3x.png b/Telegram/Resources/icons/calls_mute_tooltip@3x.png new file mode 100644 index 000000000..1cbef8aed Binary files /dev/null and b/Telegram/Resources/icons/calls_mute_tooltip@3x.png differ diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 3e9852644..f1cb48b8d 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -1751,6 +1751,18 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_call_rate_label" = "Please rate the quality of your call"; "lng_call_rate_comment" = "Comment (optional)"; +"lng_call_start_video" = "Start Video"; +"lng_call_stop_video" = "Stop Video"; +"lng_call_end_call" = "End Call"; +"lng_call_mute_audio" = "Mute"; +"lng_call_unmute_audio" = "Unmute"; +"lng_call_accept" = "Accept"; +"lng_call_decline" = "Decline"; +"lng_call_redial" = "Redial"; +"lng_call_cancel" = "Cancel"; + +"lng_call_microphone_off" = "{user}'s microphone is off"; + "lng_no_mic_permission" = "Telegram needs access to your microphone so that you can make calls and record voice messages."; "lng_player_message_today" = "Today at {time}"; diff --git a/Telegram/SourceFiles/calls/calls.style b/Telegram/SourceFiles/calls/calls.style index 7a3a8917d..f9ee36efb 100644 --- a/Telegram/SourceFiles/calls/calls.style +++ b/Telegram/SourceFiles/calls/calls.style @@ -37,7 +37,7 @@ callHeightMin: 440px; callWidth: 720px; callHeight: 540px; -callBottomControlsHeight: 85px; +callBottomControlsHeight: 87px; CallBodyLayout { height: pixels; @@ -84,6 +84,10 @@ callFingerprintTop: 11px; callFingerprintSkip: 3px; callFingerprintBottom: -16px; +callTooltipMutedIcon: icon{{ "calls_mute_tooltip", toastFg }}; +callTooltipMutedIconPosition: point(8px, 4px); +callTooltipPadding: margins(41px, 6px, 15px, 7px); + callButton: IconButton { width: 68px; height: 68px; @@ -169,6 +173,7 @@ callCameraUnmute: CallButton(callMicrophoneUnmute) { } } } +callBottomShadowSize: 124px; callName: FlatLabel(defaultFlatLabel) { minWidth: 260px; @@ -192,6 +197,11 @@ callStatus: FlatLabel(defaultFlatLabel) { linkFontOver: font(14px underline); } } +callRemoteAudioMute: FlatLabel(callStatus) { + minWidth: 0px; + textFg: toastFg; +} +callRemoteAudioMuteSkip: 12px; callBarHeight: 38px; callBarMuteToggle: IconButton { diff --git a/Telegram/SourceFiles/calls/calls_panel.cpp b/Telegram/SourceFiles/calls/calls_panel.cpp index e4c22210f..8b05348d6 100644 --- a/Telegram/SourceFiles/calls/calls_panel.cpp +++ b/Telegram/SourceFiles/calls/calls_panel.cpp @@ -25,6 +25,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/effects/ripple_animation.h" #include "ui/image/image.h" #include "ui/wrap/fade_wrap.h" +#include "ui/wrap/padding_wrap.h" #include "ui/platform/ui_platform_utility.h" #include "ui/empty_userpic.h" #include "ui/emoji_config.h" @@ -287,6 +288,7 @@ Panel::Panel(not_null call) initWidget(); initControls(); initLayout(); + initBottomShadow(); showAndActivate(); } @@ -475,6 +477,15 @@ void Panel::reinitWithCall(Call *call) { ) | rpl::map([=](Call::RemoteAudioState state) { return (state == Call::RemoteAudioState::Muted); }); + rpl::duplicate( + remoteMuted + ) | rpl::start_with_next([=](bool muted) { + if (muted) { + createRemoteAudioMute(); + } else { + _remoteAudioMute.destroy(); + } + }, _callLifetime); _userpic = std::make_unique( widget(), _user, @@ -541,6 +552,37 @@ void Panel::reinitWithCall(Call *call) { updateStatusText(_call->state()); } +void Panel::createRemoteAudioMute() { + _remoteAudioMute.create( + widget(), + object_ptr( + widget(), + tr::lng_call_microphone_off( + lt_user, + rpl::single(_user->shortName())), + st::callRemoteAudioMute), + st::callTooltipPadding); + + _remoteAudioMute->paintRequest( + ) | rpl::start_with_next([=] { + auto p = QPainter(_remoteAudioMute); + const auto height = _remoteAudioMute->height(); + + auto hq = PainterHighQualityEnabler(p); + p.setBrush(st::toastBg); + p.setPen(Qt::NoPen); + p.drawRoundedRect(_remoteAudioMute->rect(), height / 2, height / 2); + + st::callTooltipMutedIcon.paint( + p, + st::callTooltipMutedIconPosition, + _remoteAudioMute->width()); + }, _remoteAudioMute->lifetime()); + + showControls(); + updateControlsGeometry(); +} + void Panel::initLayout() { initGeometry(); @@ -563,6 +605,9 @@ void Panel::initLayout() { #endif // Q_OS_WIN } +void Panel::initBottomShadow() { +} + void Panel::showControls() { Expects(_call != nullptr); @@ -574,6 +619,9 @@ void Panel::showControls() { _name->setVisible(!shown); _status->setVisible(!shown); _userpic->setVisible(!shown); + if (_remoteAudioMute) { + _remoteAudioMute->setVisible(shown); + } } void Panel::hideBeforeDestroy() { @@ -698,6 +746,14 @@ void Panel::updateControlsGeometry() { _bodyTop + _bodySt->nameTop); updateStatusGeometry(); + if (_remoteAudioMute) { + _remoteAudioMute->moveToLeft( + (widget()->width() - _remoteAudioMute->width()) / 2, + (_buttonsTop + - st::callRemoteAudioMuteSkip + - _remoteAudioMute->height())); + } + if (_outgoingPreviewInBody) { _outgoingVideoBubble->updateGeometry( VideoBubble::DragMode::None, diff --git a/Telegram/SourceFiles/calls/calls_panel.h b/Telegram/SourceFiles/calls/calls_panel.h index 5ba75ac69..30a3d38ca 100644 --- a/Telegram/SourceFiles/calls/calls_panel.h +++ b/Telegram/SourceFiles/calls/calls_panel.h @@ -26,6 +26,8 @@ class IconButton; class FlatLabel; template class FadeWrap; +template +class PaddingWrap; class Window; namespace Platform { class TitleControls; @@ -39,6 +41,7 @@ struct CallBodyLayout; namespace Calls { +class Tooltip; class Userpic; class SignalBars; class VideoBubble; @@ -73,6 +76,7 @@ private: void reinitWithCall(Call *call); void initLayout(); void initGeometry(); + void initBottomShadow(); void handleClose(); void handleMouseMove(not_null e); @@ -94,6 +98,7 @@ private: void refreshOutgoingPreviewInBody(State state); void toggleFullScreen(bool fullscreen); + void createRemoteAudioMute(); [[nodiscard]] QRect incomingFrameGeometry() const; [[nodiscard]] QRect outgoingFrameGeometry() const; @@ -123,10 +128,12 @@ private: object_ptr _name; object_ptr _status; object_ptr _signalBars = { nullptr }; + object_ptr> _remoteAudioMute = { nullptr }; std::unique_ptr _userpic; std::unique_ptr _outgoingVideoBubble; std::vector _fingerprint; QRect _fingerprintArea; + QPixmap _bottomShadow; int _bodyTop = 0; int _buttonsTop = 0; int _fingerprintHeight = 0;