Toggle fullscreen by mute button in RTMP streams.

This commit is contained in:
John Preston 2022-02-28 16:14:28 +03:00
parent 25e29d3dd5
commit fc5ed46b40
11 changed files with 405 additions and 308 deletions

View file

@ -270,6 +270,9 @@ callMuteMajorBlobMinRadius: 67px;
callMuteMajorBlobMaxRadius: 77px; callMuteMajorBlobMaxRadius: 77px;
callMuteBlobRadiusForDiameter: 100px; callMuteBlobRadiusForDiameter: 100px;
callMuteToFullScreen: icon {{ "player/player_fullscreen", groupCallIconFg }};
callMuteFromFullScreen: icon {{ "player/player_minimize", groupCallIconFg }};
callConnectingRadial: InfiniteRadialAnimation(defaultInfiniteRadialAnimation) { callConnectingRadial: InfiniteRadialAnimation(defaultInfiniteRadialAnimation) {
color: lightButtonFg; color: lightButtonFg;
thickness: 4px; thickness: 4px;
@ -489,6 +492,7 @@ callErrorToast: Toast(defaultToast) {
groupCallWidth: 380px; groupCallWidth: 380px;
groupCallHeight: 580px; groupCallHeight: 580px;
groupCallHeightRtmpMin: 280px;
groupCallRipple: RippleAnimation(defaultRippleAnimation) { groupCallRipple: RippleAnimation(defaultRippleAnimation) {
color: groupCallMembersBgRipple; color: groupCallMembersBgRipple;

View file

@ -990,9 +990,10 @@ void GroupCall::playConnectingSoundOnce() {
} }
bool GroupCall::showChooseJoinAs() const { bool GroupCall::showChooseJoinAs() const {
return (_possibleJoinAs.size() > 1) return !_rtmp
&& ((_possibleJoinAs.size() > 1)
|| (_possibleJoinAs.size() == 1 || (_possibleJoinAs.size() == 1
&& !_possibleJoinAs.front()->isSelf()); && !_possibleJoinAs.front()->isSelf()));
} }
bool GroupCall::scheduleStartSubscribed() const { bool GroupCall::scheduleStartSubscribed() const {
@ -1010,6 +1011,14 @@ bool GroupCall::listenersHidden() const {
return _listenersHidden; return _listenersHidden;
} }
bool GroupCall::emptyRtmp() const {
return _emptyRtmp.current();
}
rpl::producer<bool> GroupCall::emptyRtmpValue() const {
return _emptyRtmp.value();
}
Data::GroupCall *GroupCall::lookupReal() const { Data::GroupCall *GroupCall::lookupReal() const {
const auto real = _peer->groupCall(); const auto real = _peer->groupCall();
return (real && real->id() == _id) ? real : nullptr; return (real && real->id() == _id) ? real : nullptr;
@ -2601,7 +2610,8 @@ void GroupCall::requestCurrentTimeStart(
).done([=](const MTPphone_GroupCallStreamChannels &result) { ).done([=](const MTPphone_GroupCallStreamChannels &result) {
result.match([&](const MTPDphone_groupCallStreamChannels &data) { result.match([&](const MTPDphone_groupCallStreamChannels &data) {
const auto &list = data.vchannels().v; const auto &list = data.vchannels().v;
if (!list.isEmpty()) { const auto empty = list.isEmpty();
if (!empty) {
const auto &first = list.front(); const auto &first = list.front();
first.match([&](const MTPDgroupCallStreamChannel &data) { first.match([&](const MTPDgroupCallStreamChannel &data) {
finish(data.vlast_timestamp_ms().v); finish(data.vlast_timestamp_ms().v);
@ -2609,6 +2619,7 @@ void GroupCall::requestCurrentTimeStart(
} else { } else {
finish(0); finish(0);
} }
_emptyRtmp = empty;
}); });
}).fail([=](const MTP::Error &error) { }).fail([=](const MTP::Error &error) {
finish(0); finish(0);

View file

@ -233,6 +233,8 @@ public:
[[nodiscard]] bool scheduleStartSubscribed() const; [[nodiscard]] bool scheduleStartSubscribed() const;
[[nodiscard]] bool rtmp() const; [[nodiscard]] bool rtmp() const;
[[nodiscard]] bool listenersHidden() const; [[nodiscard]] bool listenersHidden() const;
[[nodiscard]] bool emptyRtmp() const;
[[nodiscard]] rpl::producer<bool> emptyRtmpValue() const;
[[nodiscard]] Data::GroupCall *lookupReal() const; [[nodiscard]] Data::GroupCall *lookupReal() const;
[[nodiscard]] rpl::producer<not_null<Data::GroupCall*>> real() const; [[nodiscard]] rpl::producer<not_null<Data::GroupCall*>> real() const;
@ -593,6 +595,7 @@ private:
rpl::variable<MuteState> _muted = MuteState::Muted; rpl::variable<MuteState> _muted = MuteState::Muted;
rpl::variable<bool> _canManage = false; rpl::variable<bool> _canManage = false;
rpl::variable<bool> _videoIsWorking = false; rpl::variable<bool> _videoIsWorking = false;
rpl::variable<bool> _emptyRtmp = false;
bool _initialMuteStateSent = false; bool _initialMuteStateSent = false;
bool _acceptFields = false; bool _acceptFields = false;

View file

@ -1191,7 +1191,8 @@ base::unique_qptr<Ui::PopupMenu> Members::Controller::createRowContextMenu(
const auto muted = (muteState == Row::State::Muted) const auto muted = (muteState == Row::State::Muted)
|| (muteState == Row::State::RaisedHand); || (muteState == Row::State::RaisedHand);
const auto addCover = true; const auto addCover = true;
const auto addVolumeItem = !muted || isMe(participantPeer); const auto addVolumeItem = !_call->rtmp()
&& (!muted || isMe(participantPeer));
const auto admin = IsGroupCallAdmin(_peer, participantPeer); const auto admin = IsGroupCallAdmin(_peer, participantPeer);
const auto session = &_peer->session(); const auto session = &_peer->session();
const auto getCurrentWindow = [=]() -> Window::SessionController* { const auto getCurrentWindow = [=]() -> Window::SessionController* {
@ -1430,7 +1431,8 @@ void Members::Controller::addMuteActionsToContextMenu(
auto mutesFromVolume = rpl::never<bool>() | rpl::type_erased(); auto mutesFromVolume = rpl::never<bool>() | rpl::type_erased();
const auto addVolumeItem = !muted || isMe(participantPeer); const auto addVolumeItem = !_call->rtmp()
&& (!muted || isMe(participantPeer));
if (addVolumeItem) { if (addVolumeItem) {
auto otherParticipantStateValue auto otherParticipantStateValue
= _call->otherParticipantStateValue( = _call->otherParticipantStateValue(
@ -1492,6 +1494,7 @@ void Members::Controller::addMuteActionsToContextMenu(
const auto muteAction = [&]() -> QAction* { const auto muteAction = [&]() -> QAction* {
if (muteState == Row::State::Invited if (muteState == Row::State::Invited
|| _call->rtmp()
|| isMe(participantPeer) || isMe(participantPeer)
|| (muteState == Row::State::Inactive || (muteState == Row::State::Inactive
&& participantIsCallAdmin && participantIsCallAdmin

View file

@ -114,6 +114,9 @@ Panel::Panel(not_null<GroupCall*> call)
: _call->scheduleStartSubscribed() : _call->scheduleStartSubscribed()
? Ui::CallMuteButtonType::ScheduledNotify ? Ui::CallMuteButtonType::ScheduledNotify
: Ui::CallMuteButtonType::ScheduledSilent), : Ui::CallMuteButtonType::ScheduledSilent),
.expandType = ((_call->scheduleDate() || !_call->rtmp())
? Ui::CallMuteButtonExpandType::None
: Ui::CallMuteButtonExpandType::Normal),
})) }))
, _hangup(widget(), st::groupCallHangup) , _hangup(widget(), st::groupCallHangup)
, _stickedTooltipsShown(Core::App().settings().hiddenGroupCallTooltips() , _stickedTooltipsShown(Core::App().settings().hiddenGroupCallTooltips()
@ -257,22 +260,34 @@ void Panel::initWindow() {
return base::EventFilterResult::Cancel; return base::EventFilterResult::Cancel;
} else if (e->type() == QEvent::KeyPress } else if (e->type() == QEvent::KeyPress
|| e->type() == QEvent::KeyRelease) { || e->type() == QEvent::KeyRelease) {
if (static_cast<QKeyEvent*>(e.get())->key() == Qt::Key_Space) { const auto key = static_cast<QKeyEvent*>(e.get())->key();
if (key == Qt::Key_Space) {
_call->pushToTalk( _call->pushToTalk(
e->type() == QEvent::KeyPress, e->type() == QEvent::KeyPress,
kSpacePushToTalkDelay); kSpacePushToTalkDelay);
} else if (key == Qt::Key_Escape && _fullScreen.current()) {
toggleFullScreen(false);
} }
} }
return base::EventFilterResult::Continue; return base::EventFilterResult::Continue;
}); });
QObject::connect(
window()->windowHandle(),
&QWindow::windowStateChanged,
[=](Qt::WindowState state) {
_fullScreen = (state == Qt::WindowFullScreen);
});
window()->setBodyTitleArea([=](QPoint widgetPoint) { window()->setBodyTitleArea([=](QPoint widgetPoint) {
using Flag = Ui::WindowTitleHitTestFlag; using Flag = Ui::WindowTitleHitTestFlag;
const auto titleRect = QRect( const auto titleRect = QRect(
0, 0,
0, 0,
widget()->width(), widget()->width(),
st::groupCallMembersTop); (mode() == PanelMode::Wide
? st::groupCallWideVideoTop
: st::groupCallMembersTop));
const auto moveable = (titleRect.contains(widgetPoint) const auto moveable = (titleRect.contains(widgetPoint)
&& (!_menuToggle || !_menuToggle->geometry().contains(widgetPoint)) && (!_menuToggle || !_menuToggle->geometry().contains(widgetPoint))
&& (!_menu || !_menu->geometry().contains(widgetPoint)) && (!_menu || !_menu->geometry().contains(widgetPoint))
@ -365,7 +380,11 @@ void Panel::initControls() {
!real->scheduleStartSubscribed()); !real->scheduleStartSubscribed());
} }
return; return;
} else if (_call->rtmp()) {
toggleFullScreen(!_fullScreen.current());
return;
} }
const auto oldState = _call->muted(); const auto oldState = _call->muted();
const auto newState = (oldState == MuteState::ForceMuted) const auto newState = (oldState == MuteState::ForceMuted)
? MuteState::RaisedHand ? MuteState::RaisedHand
@ -450,6 +469,14 @@ void Panel::initControls() {
refreshControlsBackground(); refreshControlsBackground();
} }
void Panel::toggleFullScreen(bool fullscreen) {
if (fullscreen) {
window()->showFullScreen();
} else {
window()->showNormal();
}
}
void Panel::refreshLeftButton() { void Panel::refreshLeftButton() {
const auto share = _call->scheduleDate() const auto share = _call->scheduleDate()
&& _peer->isBroadcast() && _peer->isBroadcast()
@ -467,6 +494,7 @@ void Panel::refreshLeftButton() {
_settings->setClickedCallback([=] { _settings->setClickedCallback([=] {
showBox(Box(SettingsBox, _call)); showBox(Box(SettingsBox, _call));
}); });
trackControls(_trackControls, true);
} }
const auto raw = _callShare ? _callShare.data() : _settings.data(); const auto raw = _callShare ? _callShare.data() : _settings.data();
raw->show(); raw->show();
@ -615,7 +643,8 @@ void Panel::setupRealMuteButtonState(not_null<Data::GroupCall*> real) {
real->scheduleDateValue(), real->scheduleDateValue(),
real->scheduleStartSubscribedValue(), real->scheduleStartSubscribedValue(),
_call->canManageValue(), _call->canManageValue(),
_mode.value() _mode.value(),
_fullScreen.value()
) | rpl::distinct_until_changed( ) | rpl::distinct_until_changed(
) | rpl::filter( ) | rpl::filter(
_2 != GroupCall::InstanceState::TransitionToRtc _2 != GroupCall::InstanceState::TransitionToRtc
@ -625,9 +654,11 @@ void Panel::setupRealMuteButtonState(not_null<Data::GroupCall*> real) {
TimeId scheduleDate, TimeId scheduleDate,
bool scheduleStartSubscribed, bool scheduleStartSubscribed,
bool canManage, bool canManage,
PanelMode mode) { PanelMode mode,
bool fullScreen) {
const auto wide = (mode == PanelMode::Wide); const auto wide = (mode == PanelMode::Wide);
using Type = Ui::CallMuteButtonType; using Type = Ui::CallMuteButtonType;
using ExpandType = Ui::CallMuteButtonExpandType;
_mute->setState(Ui::CallMuteButtonState{ _mute->setState(Ui::CallMuteButtonState{
.text = (wide .text = (wide
? QString() ? QString()
@ -664,6 +695,11 @@ void Panel::setupRealMuteButtonState(not_null<Data::GroupCall*> real) {
: mute == MuteState::Muted : mute == MuteState::Muted
? Type::Muted ? Type::Muted
: Type::Active), : Type::Active),
.expandType = ((scheduleDate || !_call->rtmp())
? ExpandType::None
: fullScreen
? ExpandType::Expanded
: ExpandType::Normal),
}); });
}, _callLifetime); }, _callLifetime);
} }
@ -860,8 +896,10 @@ void Panel::minimizeVideo() {
} }
const auto available = window()->screen()->availableGeometry(); const auto available = window()->screen()->availableGeometry();
const auto width = st::groupCallWidth; const auto width = st::groupCallWidth;
const auto height = st::groupCallHeight; const auto height = _call->rtmp()
auto geometry = QRect( ? st::groupCallHeightRtmpMin
: st::groupCallHeight;
const auto geometry = QRect(
window()->x() + (window()->width() - width) / 2, window()->x() + (window()->width() - width) / 2,
window()->y() + (window()->height() - height) / 2, window()->y() + (window()->height() - height) / 2,
width, width,
@ -1277,13 +1315,14 @@ void Panel::showMainMenu() {
if (wide) { if (wide) {
_wideMenu->installEventFilter(_menu); _wideMenu->installEventFilter(_menu);
trackControl(_menu, _trackControlsMenuLifetime);
const auto x = st::groupCallWideMenuPosition.x(); const auto x = st::groupCallWideMenuPosition.x();
const auto y = st::groupCallWideMenuPosition.y(); const auto y = st::groupCallWideMenuPosition.y();
_menu->moveToLeft( _menu->moveToLeft(
_wideMenu->x() + x, _wideMenu->x() + x,
_wideMenu->y() - _menu->height() + y); _wideMenu->y() - _menu->height() + y);
_menu->showAnimated(Ui::PanelAnimation::Origin::BottomLeft); _menu->showAnimated(Ui::PanelAnimation::Origin::BottomLeft);
trackControl(_menu, _trackControlsMenuLifetime);
} else { } else {
_menuToggle->installEventFilter(_menu); _menuToggle->installEventFilter(_menu);
const auto x = st::groupCallMenuPosition.x(); const auto x = st::groupCallMenuPosition.x();
@ -1404,7 +1443,10 @@ rpl::lifetime &Panel::lifetime() {
void Panel::initGeometry() { void Panel::initGeometry() {
const auto center = Core::App().getPointForCallPanelCenter(); const auto center = Core::App().getPointForCallPanelCenter();
const auto rect = QRect(0, 0, st::groupCallWidth, st::groupCallHeight); const auto height = (_call->rtmp() && !_call->canManage())
? st::groupCallHeightRtmpMin
: st::groupCallHeight;
const auto rect = QRect(0, 0, st::groupCallWidth, height);
window()->setGeometry(rect.translated(center - rect.center())); window()->setGeometry(rect.translated(center - rect.center()));
window()->setMinimumSize(rect.size()); window()->setMinimumSize(rect.size());
window()->show(); window()->show();
@ -1854,15 +1896,14 @@ void Panel::updateTooltipGeometry() {
_niceTooltip->pointAt(geometry, RectPart::Top, countPosition); _niceTooltip->pointAt(geometry, RectPart::Top, countPosition);
} }
void Panel::trackControls(bool track) { void Panel::trackControls(bool track, bool force) {
if (_trackControls == track) { if (!force && _trackControls == track) {
return; return;
} }
_trackControls = track; _trackControls = track;
if (!track) {
_trackControlsLifetime.destroy();
_trackControlsOverStateLifetime.destroy(); _trackControlsOverStateLifetime.destroy();
_trackControlsMenuLifetime.destroy(); _trackControlsMenuLifetime.destroy();
if (!track) {
toggleWideControls(true); toggleWideControls(true);
if (_wideControlsAnimation.animating()) { if (_wideControlsAnimation.animating()) {
_wideControlsAnimation.stop(); _wideControlsAnimation.stop();
@ -1932,12 +1973,13 @@ void Panel::updateButtonsGeometry() {
Assert(_settings != nullptr); Assert(_settings != nullptr);
Assert(_callShare == nullptr); Assert(_callShare == nullptr);
const auto rtmp = _call->rtmp();
const auto shown = _wideControlsAnimation.value( const auto shown = _wideControlsAnimation.value(
_wideControlsShown ? 1. : 0.); _wideControlsShown ? 1. : 0.);
const auto hidden = (shown == 0.); const auto hidden = (shown == 0.);
if (_viewport) { if (_viewport) {
_viewport->setControlsShown(_call->rtmp() ? 0. : shown); _viewport->setControlsShown(rtmp ? 0. : shown);
} }
const auto buttonsTop = widget()->height() - anim::interpolate( const auto buttonsTop = widget()->height() - anim::interpolate(
@ -1947,8 +1989,8 @@ void Panel::updateButtonsGeometry() {
const auto addSkip = st::callMuteButtonSmall.active.outerRadius; const auto addSkip = st::callMuteButtonSmall.active.outerRadius;
const auto muteSize = _mute->innerSize().width() + 2 * addSkip; const auto muteSize = _mute->innerSize().width() + 2 * addSkip;
const auto skip = st::groupCallButtonSkipSmall; const auto skip = st::groupCallButtonSkipSmall;
const auto fullWidth = (_video->width() + skip) const auto fullWidth = (rtmp ? 0 : (_video->width() + skip))
+ (_screenShare->width() + skip) + (rtmp ? 0 : (_screenShare->width() + skip))
+ (muteSize + skip) + (muteSize + skip)
+ (_settings->width() + skip) + (_settings->width() + skip)
+ _hangup->width(); + _hangup->width();
@ -1960,12 +2002,20 @@ void Panel::updateButtonsGeometry() {
- membersWidth - membersWidth
- membersSkip - membersSkip
- fullWidth) / 2; - fullWidth) / 2;
toggle(_screenShare, !hidden); toggle(_screenShare, !hidden && !rtmp);
if (!rtmp) {
_screenShare->moveToLeft(left, buttonsTop); _screenShare->moveToLeft(left, buttonsTop);
left += _screenShare->width() + skip; left += _screenShare->width() + skip;
toggle(_video, !hidden); }
toggle(_video, !hidden && !rtmp);
if (!rtmp) {
_video->moveToLeft(left, buttonsTop); _video->moveToLeft(left, buttonsTop);
left += _video->width() + skip; left += _video->width() + skip;
} else {
_wideMenu->moveToLeft(left, buttonsTop);
_settings->moveToLeft(left, buttonsTop);
left += _settings->width() + skip;
}
toggle(_mute, !hidden); toggle(_mute, !hidden);
_mute->moveInner({ left + addSkip, buttonsTop + addSkip }); _mute->moveInner({ left + addSkip, buttonsTop + addSkip });
left += muteSize + skip; left += muteSize + skip;
@ -1973,9 +2023,11 @@ void Panel::updateButtonsGeometry() {
|| _call->showChooseJoinAs(); || _call->showChooseJoinAs();
toggle(_settings, !hidden && !wideMenuShown); toggle(_settings, !hidden && !wideMenuShown);
toggle(_wideMenu, !hidden && wideMenuShown); toggle(_wideMenu, !hidden && wideMenuShown);
if (!rtmp) {
_wideMenu->moveToLeft(left, buttonsTop); _wideMenu->moveToLeft(left, buttonsTop);
_settings->moveToLeft(left, buttonsTop); _settings->moveToLeft(left, buttonsTop);
left += _settings->width() + skip; left += _settings->width() + skip;
}
toggle(_hangup, !hidden); toggle(_hangup, !hidden);
_hangup->moveToLeft(left, buttonsTop); _hangup->moveToLeft(left, buttonsTop);
left += _hangup->width(); left += _hangup->width();

View file

@ -130,7 +130,8 @@ private:
bool handleClose(); bool handleClose();
void startScheduledNow(); void startScheduledNow();
void trackControls(bool track); void toggleFullScreen(bool fullscreen);
void trackControls(bool track, bool force = false);
void raiseControls(); void raiseControls();
void enlargeVideo(); void enlargeVideo();
void minimizeVideo(); void minimizeVideo();
@ -197,6 +198,7 @@ private:
Ui::GL::Window _window; Ui::GL::Window _window;
const std::unique_ptr<Ui::LayerManager> _layerBg; const std::unique_ptr<Ui::LayerManager> _layerBg;
rpl::variable<PanelMode> _mode; rpl::variable<PanelMode> _mode;
rpl::variable<bool> _fullScreen = false;
#ifndef Q_OS_MAC #ifndef Q_OS_MAC
std::unique_ptr<Ui::Platform::SeparateTitleControls> _controls; std::unique_ptr<Ui::Platform::SeparateTitleControls> _controls;
@ -215,7 +217,6 @@ private:
object_ptr<Ui::AbstractButton> _joinAsToggle = { nullptr }; object_ptr<Ui::AbstractButton> _joinAsToggle = { nullptr };
object_ptr<Members> _members = { nullptr }; object_ptr<Members> _members = { nullptr };
std::unique_ptr<Viewport> _viewport; std::unique_ptr<Viewport> _viewport;
rpl::lifetime _trackControlsLifetime;
rpl::lifetime _trackControlsOverStateLifetime; rpl::lifetime _trackControlsOverStateLifetime;
rpl::lifetime _trackControlsMenuLifetime; rpl::lifetime _trackControlsMenuLifetime;
object_ptr<Ui::FlatLabel> _startsIn = { nullptr }; object_ptr<Ui::FlatLabel> _startsIn = { nullptr };

View file

@ -235,6 +235,7 @@ void SettingsBox(
const auto peer = call->peer(); const auto peer = call->peer();
const auto state = box->lifetime().make_state<State>(); const auto state = box->lifetime().make_state<State>();
const auto real = peer->groupCall(); const auto real = peer->groupCall();
const auto rtmp = call->rtmp();
const auto id = call->id(); const auto id = call->id();
const auto goodReal = (real && real->id() == id); const auto goodReal = (real && real->id() == id);
@ -274,6 +275,7 @@ void SettingsBox(
}), &st::groupCallCheckbox, &st::groupCallRadio)); }), &st::groupCallCheckbox, &st::groupCallRadio));
}); });
if (!rtmp) {
AddButtonWithLabel( AddButtonWithLabel(
layout, layout,
tr::lng_group_call_microphone(), tr::lng_group_call_microphone(),
@ -327,7 +329,6 @@ void SettingsBox(
Core::App().saveSettingsDelayed(); Core::App().saveSettingsDelayed();
}, layout->lifetime()); }, layout->lifetime());
using GlobalShortcut = base::GlobalShortcut; using GlobalShortcut = base::GlobalShortcut;
struct PushToTalkState { struct PushToTalkState {
rpl::variable<QString> recordText = tr::lng_group_call_ptt_shortcut(); rpl::variable<QString> recordText = tr::lng_group_call_ptt_shortcut();
@ -547,7 +548,7 @@ void SettingsBox(
AddSkip(layout); AddSkip(layout);
//AddDivider(layout); //AddDivider(layout);
//AddSkip(layout); //AddSkip(layout);
}
auto shareLink = Fn<void()>(); auto shareLink = Fn<void()>();
if (peer->isChannel() if (peer->isChannel()
&& peer->asChannel()->hasUsername() && peer->asChannel()->hasUsername()
@ -644,6 +645,7 @@ void SettingsBox(
}); });
} }
if (!rtmp) {
box->setShowFinishedCallback([=] { box->setShowFinishedCallback([=] {
// Means we finished showing the box. // Means we finished showing the box.
crl::on_main(box, [=] { crl::on_main(box, [=] {
@ -653,6 +655,7 @@ void SettingsBox(
state->levelUpdateTimer.callEach(kMicTestUpdateInterval); state->levelUpdateTimer.callEach(kMicTestUpdateInterval);
}); });
}); });
}
box->setTitle(tr::lng_group_call_settings_title()); box->setTitle(tr::lng_group_call_settings_title());
box->boxClosing( box->boxClosing(

View file

@ -876,6 +876,9 @@ rpl::producer<QString> MuteButtonTooltip(not_null<GroupCall*> call) {
// : tr::lng_group_call_set_reminder(); // : tr::lng_group_call_set_reminder();
// }) | rpl::flatten_latest(); // }) | rpl::flatten_latest();
// } // }
if (call->rtmp()) {
return nullptr;
}
return call->mutedValue( return call->mutedValue(
) | rpl::map([](MuteState muted) { ) | rpl::map([](MuteState muted) {
switch (muted) { switch (muted) {

View file

@ -492,7 +492,7 @@ void GroupCall::processQueuedUpdates() {
} }
void GroupCall::computeParticipantsCount() { void GroupCall::computeParticipantsCount() {
_fullCount = _allParticipantsLoaded _fullCount = (_allParticipantsLoaded && !_listenersHidden)
? int(_participants.size()) ? int(_participants.size())
: std::max(int(_participants.size()), _serverParticipantsCount); : std::max(int(_participants.size()), _serverParticipantsCount);
} }

View file

@ -825,7 +825,17 @@ void CallMuteButton::init() {
) | rpl::start_with_next([=](QRect clip) { ) | rpl::start_with_next([=](QRect clip) {
Painter p(_content); Painter p(_content);
_icons[_iconState.index]->paint(p, _muteIconRect.x(), _muteIconRect.y()); const auto expand = _state.current().expandType;
if (expand == CallMuteButtonExpandType::Expanded) {
st::callMuteFromFullScreen.paintInCenter(p, _muteIconRect);
} else if (expand == CallMuteButtonExpandType::Normal) {
st::callMuteToFullScreen.paintInCenter(p, _muteIconRect);
} else {
_icons[_iconState.index]->paint(
p,
_muteIconRect.x(),
_muteIconRect.y());
}
if (_radialInfo.state.has_value() && _switchAnimation.animating()) { if (_radialInfo.state.has_value() && _switchAnimation.animating()) {
const auto radialProgress = _radialInfo.realShowProgress; const auto radialProgress = _radialInfo.realShowProgress;

View file

@ -43,11 +43,18 @@ enum class CallMuteButtonType {
ScheduledNotify, ScheduledNotify,
}; };
enum class CallMuteButtonExpandType {
None,
Normal,
Expanded,
};
struct CallMuteButtonState { struct CallMuteButtonState {
QString text; QString text;
QString subtext; QString subtext;
QString tooltip; QString tooltip;
CallMuteButtonType type = CallMuteButtonType::Connecting; CallMuteButtonType type = CallMuteButtonType::Connecting;
CallMuteButtonExpandType expandType = CallMuteButtonExpandType::None;
}; };
class CallMuteButton final : private AbstractTooltipShower { class CallMuteButton final : private AbstractTooltipShower {