mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-15 21:57:10 +02:00
Add empty group call panel.
This commit is contained in:
parent
25f3c14780
commit
8833d3e45b
6 changed files with 588 additions and 2 deletions
|
@ -266,6 +266,8 @@ PRIVATE
|
|||
calls/calls_call.h
|
||||
calls/calls_group_call.cpp
|
||||
calls/calls_group_call.h
|
||||
calls/calls_group_panel.cpp
|
||||
calls/calls_group_panel.h
|
||||
calls/calls_emoji_fingerprint.cpp
|
||||
calls/calls_emoji_fingerprint.h
|
||||
calls/calls_instance.cpp
|
||||
|
|
|
@ -399,3 +399,6 @@ callTitleShadow: icon {{ "calls_shadow_controls", windowShadowFg }};
|
|||
callErrorToast: Toast(defaultToast) {
|
||||
minWidth: 240px;
|
||||
}
|
||||
|
||||
groupCallWidth: 380px;
|
||||
groupCallHeight: 580px;
|
||||
|
|
462
Telegram/SourceFiles/calls/calls_group_panel.cpp
Normal file
462
Telegram/SourceFiles/calls/calls_group_panel.cpp
Normal file
|
@ -0,0 +1,462 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "calls/calls_group_panel.h"
|
||||
|
||||
#include "data/data_photo.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_user.h"
|
||||
#include "data/data_file_origin.h"
|
||||
#include "data/data_photo_media.h"
|
||||
#include "data/data_cloud_file.h"
|
||||
#include "data/data_changes.h"
|
||||
#include "calls/calls_emoji_fingerprint.h"
|
||||
#include "calls/calls_signal_bars.h"
|
||||
#include "calls/calls_userpic.h"
|
||||
#include "calls/calls_video_bubble.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/labels.h"
|
||||
#include "ui/widgets/shadow.h"
|
||||
#include "ui/widgets/window.h"
|
||||
#include "ui/effects/ripple_animation.h"
|
||||
#include "ui/image/image.h"
|
||||
#include "ui/text/format_values.h"
|
||||
#include "ui/wrap/fade_wrap.h"
|
||||
#include "ui/wrap/padding_wrap.h"
|
||||
#include "ui/platform/ui_platform_utility.h"
|
||||
#include "ui/toast/toast.h"
|
||||
#include "ui/empty_userpic.h"
|
||||
#include "ui/emoji_config.h"
|
||||
#include "core/application.h"
|
||||
#include "mainwindow.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "main/main_session.h"
|
||||
#include "apiwrap.h"
|
||||
#include "platform/platform_specific.h"
|
||||
#include "base/platform/base_platform_info.h"
|
||||
#include "window/main_window.h"
|
||||
#include "app.h"
|
||||
#include "webrtc/webrtc_video_track.h"
|
||||
#include "styles/style_calls.h"
|
||||
#include "styles/style_chat.h"
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#include "ui/platform/win/ui_window_title_win.h"
|
||||
#endif // Q_OS_WIN
|
||||
|
||||
#include <QtWidgets/QDesktopWidget>
|
||||
#include <QtWidgets/QApplication>
|
||||
#include <QtGui/QWindow>
|
||||
|
||||
namespace Calls {
|
||||
|
||||
class GroupPanel::Button final : public Ui::RippleButton {
|
||||
public:
|
||||
Button(
|
||||
QWidget *parent,
|
||||
const style::CallButton &stFrom,
|
||||
const style::CallButton *stTo = nullptr);
|
||||
|
||||
void setProgress(float64 progress);
|
||||
void setText(rpl::producer<QString> text);
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *e) override;
|
||||
|
||||
void onStateChanged(State was, StateChangeSource source) override;
|
||||
|
||||
QImage prepareRippleMask() const override;
|
||||
QPoint prepareRippleStartPosition() const override;
|
||||
|
||||
private:
|
||||
QPoint iconPosition(not_null<const style::CallButton*> st) const;
|
||||
void mixIconMasks();
|
||||
|
||||
not_null<const style::CallButton*> _stFrom;
|
||||
const style::CallButton *_stTo = nullptr;
|
||||
float64 _progress = 0.;
|
||||
|
||||
object_ptr<Ui::FlatLabel> _label = { nullptr };
|
||||
|
||||
QImage _bgMask, _bg;
|
||||
QPixmap _bgFrom, _bgTo;
|
||||
QImage _iconMixedMask, _iconFrom, _iconTo, _iconMixed;
|
||||
|
||||
};
|
||||
|
||||
GroupPanel::Button::Button(
|
||||
QWidget *parent,
|
||||
const style::CallButton &stFrom,
|
||||
const style::CallButton *stTo)
|
||||
: Ui::RippleButton(parent, stFrom.button.ripple)
|
||||
, _stFrom(&stFrom)
|
||||
, _stTo(stTo) {
|
||||
resize(_stFrom->button.width, _stFrom->button.height);
|
||||
|
||||
_bgMask = prepareRippleMask();
|
||||
_bgFrom = App::pixmapFromImageInPlace(style::colorizeImage(_bgMask, _stFrom->bg));
|
||||
if (_stTo) {
|
||||
Assert(_stFrom->button.width == _stTo->button.width);
|
||||
Assert(_stFrom->button.height == _stTo->button.height);
|
||||
Assert(_stFrom->button.rippleAreaPosition == _stTo->button.rippleAreaPosition);
|
||||
Assert(_stFrom->button.rippleAreaSize == _stTo->button.rippleAreaSize);
|
||||
|
||||
_bg = QImage(_bgMask.size(), QImage::Format_ARGB32_Premultiplied);
|
||||
_bg.setDevicePixelRatio(cRetinaFactor());
|
||||
_bgTo = App::pixmapFromImageInPlace(style::colorizeImage(_bgMask, _stTo->bg));
|
||||
_iconMixedMask = QImage(_bgMask.size(), QImage::Format_ARGB32_Premultiplied);
|
||||
_iconMixedMask.setDevicePixelRatio(cRetinaFactor());
|
||||
_iconFrom = QImage(_bgMask.size(), QImage::Format_ARGB32_Premultiplied);
|
||||
_iconFrom.setDevicePixelRatio(cRetinaFactor());
|
||||
_iconFrom.fill(Qt::black);
|
||||
{
|
||||
Painter p(&_iconFrom);
|
||||
p.drawImage((_stFrom->button.rippleAreaSize - _stFrom->button.icon.width()) / 2, (_stFrom->button.rippleAreaSize - _stFrom->button.icon.height()) / 2, _stFrom->button.icon.instance(Qt::white));
|
||||
}
|
||||
_iconTo = QImage(_bgMask.size(), QImage::Format_ARGB32_Premultiplied);
|
||||
_iconTo.setDevicePixelRatio(cRetinaFactor());
|
||||
_iconTo.fill(Qt::black);
|
||||
{
|
||||
Painter p(&_iconTo);
|
||||
p.drawImage((_stTo->button.rippleAreaSize - _stTo->button.icon.width()) / 2, (_stTo->button.rippleAreaSize - _stTo->button.icon.height()) / 2, _stTo->button.icon.instance(Qt::white));
|
||||
}
|
||||
_iconMixed = QImage(_bgMask.size(), QImage::Format_ARGB32_Premultiplied);
|
||||
_iconMixed.setDevicePixelRatio(cRetinaFactor());
|
||||
}
|
||||
}
|
||||
|
||||
void GroupPanel::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 GroupPanel::Button::setProgress(float64 progress) {
|
||||
_progress = progress;
|
||||
update();
|
||||
}
|
||||
|
||||
void GroupPanel::Button::paintEvent(QPaintEvent *e) {
|
||||
Painter p(this);
|
||||
|
||||
auto bgPosition = myrtlpoint(_stFrom->button.rippleAreaPosition);
|
||||
auto paintFrom = (_progress == 0.) || !_stTo;
|
||||
auto paintTo = !paintFrom && (_progress == 1.);
|
||||
|
||||
if (paintFrom) {
|
||||
p.drawPixmap(bgPosition, _bgFrom);
|
||||
} else if (paintTo) {
|
||||
p.drawPixmap(bgPosition, _bgTo);
|
||||
} else {
|
||||
style::colorizeImage(_bgMask, anim::color(_stFrom->bg, _stTo->bg, _progress), &_bg);
|
||||
p.drawImage(bgPosition, _bg);
|
||||
}
|
||||
|
||||
auto rippleColorInterpolated = QColor();
|
||||
auto rippleColorOverride = &rippleColorInterpolated;
|
||||
if (paintFrom) {
|
||||
rippleColorOverride = nullptr;
|
||||
} else if (paintTo) {
|
||||
rippleColorOverride = &_stTo->button.ripple.color->c;
|
||||
} else {
|
||||
rippleColorInterpolated = anim::color(_stFrom->button.ripple.color, _stTo->button.ripple.color, _progress);
|
||||
}
|
||||
paintRipple(p, _stFrom->button.rippleAreaPosition.x(), _stFrom->button.rippleAreaPosition.y(), rippleColorOverride);
|
||||
|
||||
auto positionFrom = iconPosition(_stFrom);
|
||||
if (paintFrom) {
|
||||
const auto icon = &_stFrom->button.icon;
|
||||
icon->paint(p, positionFrom, width());
|
||||
} else {
|
||||
auto positionTo = iconPosition(_stTo);
|
||||
if (paintTo) {
|
||||
_stTo->button.icon.paint(p, positionTo, width());
|
||||
} else {
|
||||
mixIconMasks();
|
||||
style::colorizeImage(_iconMixedMask, st::callIconFg->c, &_iconMixed);
|
||||
p.drawImage(myrtlpoint(_stFrom->button.rippleAreaPosition), _iconMixed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QPoint GroupPanel::Button::iconPosition(not_null<const style::CallButton*> st) const {
|
||||
auto result = st->button.iconPosition;
|
||||
if (result.x() < 0) {
|
||||
result.setX((width() - st->button.icon.width()) / 2);
|
||||
}
|
||||
if (result.y() < 0) {
|
||||
result.setY((height() - st->button.icon.height()) / 2);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void GroupPanel::Button::mixIconMasks() {
|
||||
_iconMixedMask.fill(Qt::black);
|
||||
|
||||
Painter p(&_iconMixedMask);
|
||||
PainterHighQualityEnabler hq(p);
|
||||
auto paintIconMask = [this, &p](const QImage &mask, float64 angle) {
|
||||
auto skipFrom = _stFrom->button.rippleAreaSize / 2;
|
||||
p.translate(skipFrom, skipFrom);
|
||||
p.rotate(angle);
|
||||
p.translate(-skipFrom, -skipFrom);
|
||||
p.drawImage(0, 0, mask);
|
||||
};
|
||||
p.save();
|
||||
paintIconMask(_iconFrom, (_stFrom->angle - _stTo->angle) * _progress);
|
||||
p.restore();
|
||||
p.setOpacity(_progress);
|
||||
paintIconMask(_iconTo, (_stTo->angle - _stFrom->angle) * (1. - _progress));
|
||||
}
|
||||
|
||||
void GroupPanel::Button::onStateChanged(State was, StateChangeSource source) {
|
||||
RippleButton::onStateChanged(was, source);
|
||||
|
||||
auto over = isOver();
|
||||
auto wasOver = static_cast<bool>(was & StateFlag::Over);
|
||||
if (over != wasOver) {
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
QPoint GroupPanel::Button::prepareRippleStartPosition() const {
|
||||
return mapFromGlobal(QCursor::pos()) - _stFrom->button.rippleAreaPosition;
|
||||
}
|
||||
|
||||
QImage GroupPanel::Button::prepareRippleMask() const {
|
||||
return Ui::RippleAnimation::ellipseMask(QSize(_stFrom->button.rippleAreaSize, _stFrom->button.rippleAreaSize));
|
||||
}
|
||||
|
||||
GroupPanel::GroupPanel(not_null<GroupCall*> call)
|
||||
: _call(call)
|
||||
, _channel(call->channel())
|
||||
, _window(std::make_unique<Ui::Window>(Core::App().getModalParent()))
|
||||
#ifdef Q_OS_WIN
|
||||
, _controls(std::make_unique<Ui::Platform::TitleControls>(
|
||||
_window.get(),
|
||||
st::callTitle,
|
||||
[=](bool maximized) { toggleFullScreen(maximized); }))
|
||||
#endif // Q_OS_WIN
|
||||
, _settings(widget(), st::callCancel)
|
||||
, _hangup(widget(), st::callHangup)
|
||||
, _mute(widget(), st::callMicrophoneMute, &st::callMicrophoneUnmute) {
|
||||
initWindow();
|
||||
initWidget();
|
||||
initControls();
|
||||
initLayout();
|
||||
showAndActivate();
|
||||
}
|
||||
|
||||
GroupPanel::~GroupPanel() = default;
|
||||
|
||||
void GroupPanel::showAndActivate() {
|
||||
_window->raise();
|
||||
_window->setWindowState(_window->windowState() | Qt::WindowActive);
|
||||
_window->activateWindow();
|
||||
_window->setFocus();
|
||||
}
|
||||
|
||||
void GroupPanel::initWindow() {
|
||||
_window->setAttribute(Qt::WA_OpaquePaintEvent);
|
||||
_window->setAttribute(Qt::WA_NoSystemBackground);
|
||||
_window->setWindowIcon(
|
||||
QIcon(QPixmap::fromImage(Image::Empty()->original(), Qt::ColorOnly)));
|
||||
_window->setTitle(u" "_q);
|
||||
_window->setTitleStyle(st::callTitle);
|
||||
|
||||
_window->events(
|
||||
) | rpl::start_with_next([=](not_null<QEvent*> e) {
|
||||
if (e->type() == QEvent::Close) {
|
||||
handleClose();
|
||||
} else if (e->type() == QEvent::KeyPress) {
|
||||
if ((static_cast<QKeyEvent*>(e.get())->key() == Qt::Key_Escape)
|
||||
&& _window->isFullScreen()) {
|
||||
_window->showNormal();
|
||||
}
|
||||
}
|
||||
}, _window->lifetime());
|
||||
|
||||
_window->setBodyTitleArea([=](QPoint widgetPoint) {
|
||||
using Flag = Ui::WindowTitleHitTestFlag;
|
||||
if (!widget()->rect().contains(widgetPoint)) {
|
||||
return Flag::None | Flag(0);
|
||||
}
|
||||
#ifdef Q_OS_WIN
|
||||
if (_controls->geometry().contains(widgetPoint)) {
|
||||
return Flag::None | Flag(0);
|
||||
}
|
||||
#endif // Q_OS_WIN
|
||||
const auto inControls = false;
|
||||
return inControls
|
||||
? Flag::None
|
||||
: (Flag::Move | Flag::FullScreen);
|
||||
});
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
// On Windows we replace snap-to-top maximizing with fullscreen.
|
||||
//
|
||||
// We have to switch first to showNormal, so that showFullScreen
|
||||
// will remember correct normal window geometry and next showNormal
|
||||
// will show it instead of a moving maximized window.
|
||||
//
|
||||
// We have to do it in InvokeQueued, otherwise it still captures
|
||||
// the maximized window geometry and saves it.
|
||||
//
|
||||
// I couldn't find a less glitchy way to do that *sigh*.
|
||||
const auto object = _window->windowHandle();
|
||||
const auto signal = &QWindow::windowStateChanged;
|
||||
QObject::connect(object, signal, [=](Qt::WindowState state) {
|
||||
if (state == Qt::WindowMaximized) {
|
||||
InvokeQueued(object, [=] {
|
||||
_window->showNormal();
|
||||
_window->showFullScreen();
|
||||
});
|
||||
}
|
||||
});
|
||||
#endif // Q_OS_WIN
|
||||
}
|
||||
|
||||
void GroupPanel::initWidget() {
|
||||
widget()->setMouseTracking(true);
|
||||
|
||||
widget()->paintRequest(
|
||||
) | rpl::start_with_next([=](QRect clip) {
|
||||
paint(clip);
|
||||
}, widget()->lifetime());
|
||||
|
||||
widget()->sizeValue(
|
||||
) | rpl::skip(1) | rpl::start_with_next([=] {
|
||||
updateControlsGeometry();
|
||||
}, widget()->lifetime());
|
||||
}
|
||||
|
||||
void GroupPanel::initControls() {
|
||||
_mute->setClickedCallback([=] {
|
||||
if (_call) {
|
||||
_call->setMuted(!_call->muted());
|
||||
}
|
||||
});
|
||||
_hangup->setClickedCallback([=] {
|
||||
if (_call) {
|
||||
_call->hangup();
|
||||
}
|
||||
});
|
||||
_settings->setClickedCallback([=] {
|
||||
});
|
||||
initWithCall(_call);
|
||||
}
|
||||
|
||||
void GroupPanel::initWithCall(GroupCall *call) {
|
||||
_callLifetime.destroy();
|
||||
_call = call;
|
||||
if (!_call) {
|
||||
return;
|
||||
}
|
||||
|
||||
_channel = _call->channel();
|
||||
|
||||
_settings->setText(tr::lng_menu_settings());
|
||||
_hangup->setText(tr::lng_box_leave());
|
||||
|
||||
_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->stateValue(
|
||||
) | rpl::start_with_next([=](State state) {
|
||||
stateChanged(state);
|
||||
}, _callLifetime);
|
||||
}
|
||||
|
||||
void GroupPanel::initLayout() {
|
||||
initGeometry();
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
_controls->raise();
|
||||
#endif // Q_OS_WIN
|
||||
}
|
||||
|
||||
void GroupPanel::showControls() {
|
||||
Expects(_call != nullptr);
|
||||
|
||||
widget()->showChildren();
|
||||
}
|
||||
|
||||
void GroupPanel::closeBeforeDestroy() {
|
||||
_window->close();
|
||||
initWithCall(nullptr);
|
||||
}
|
||||
|
||||
void GroupPanel::initGeometry() {
|
||||
const auto center = Core::App().getPointForCallPanelCenter();
|
||||
const auto rect = QRect(0, 0, st::groupCallWidth, st::groupCallHeight);
|
||||
_window->setGeometry(rect.translated(center - rect.center()));
|
||||
_window->setMinimumSize(rect.size());
|
||||
_window->show();
|
||||
updateControlsGeometry();
|
||||
}
|
||||
|
||||
void GroupPanel::toggleFullScreen(bool fullscreen) {
|
||||
if (fullscreen) {
|
||||
_window->showFullScreen();
|
||||
} else {
|
||||
_window->showNormal();
|
||||
}
|
||||
}
|
||||
|
||||
void GroupPanel::updateControlsGeometry() {
|
||||
if (widget()->size().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
const auto top = widget()->height() - 2 * _mute->height();
|
||||
_mute->move((widget()->width() - _mute->width()) / 2, top);
|
||||
_settings->moveToLeft(_settings->width(), top);
|
||||
_hangup->moveToRight(_settings->width(), top);
|
||||
}
|
||||
|
||||
void GroupPanel::paint(QRect clip) {
|
||||
Painter p(widget());
|
||||
|
||||
auto region = QRegion(clip);
|
||||
for (const auto rect : region) {
|
||||
p.fillRect(rect, st::callBgOpaque);
|
||||
}
|
||||
}
|
||||
|
||||
void GroupPanel::handleClose() {
|
||||
if (_call) {
|
||||
_call->hangup();
|
||||
}
|
||||
}
|
||||
|
||||
not_null<Ui::RpWidget*> GroupPanel::widget() const {
|
||||
return _window->body();
|
||||
}
|
||||
|
||||
void GroupPanel::stateChanged(State state) {
|
||||
Expects(_call != nullptr);
|
||||
|
||||
if ((state != State::HangingUp)
|
||||
&& (state != State::Ended)
|
||||
&& (state != State::FailedHangingUp)
|
||||
&& (state != State::Failed)) {
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Calls
|
96
Telegram/SourceFiles/calls/calls_group_panel.h
Normal file
96
Telegram/SourceFiles/calls/calls_group_panel.h
Normal file
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "base/weak_ptr.h"
|
||||
#include "base/timer.h"
|
||||
#include "base/object_ptr.h"
|
||||
#include "calls/calls_group_call.h"
|
||||
#include "ui/effects/animations.h"
|
||||
#include "ui/rp_widget.h"
|
||||
|
||||
class Image;
|
||||
|
||||
namespace Data {
|
||||
class PhotoMedia;
|
||||
class CloudImageView;
|
||||
} // namespace Data
|
||||
|
||||
namespace Ui {
|
||||
class IconButton;
|
||||
class FlatLabel;
|
||||
template <typename Widget>
|
||||
class FadeWrap;
|
||||
template <typename Widget>
|
||||
class PaddingWrap;
|
||||
class Window;
|
||||
namespace Platform {
|
||||
class TitleControls;
|
||||
} // namespace Platform
|
||||
} // namespace Ui
|
||||
|
||||
namespace style {
|
||||
struct CallSignalBars;
|
||||
struct CallBodyLayout;
|
||||
} // namespace style
|
||||
|
||||
namespace Calls {
|
||||
|
||||
class Userpic;
|
||||
class SignalBars;
|
||||
|
||||
class GroupPanel final {
|
||||
public:
|
||||
GroupPanel(not_null<GroupCall*> call);
|
||||
~GroupPanel();
|
||||
|
||||
void showAndActivate();
|
||||
void closeBeforeDestroy();
|
||||
|
||||
private:
|
||||
class Button;
|
||||
using State = GroupCall::State;
|
||||
|
||||
[[nodiscard]] not_null<Ui::RpWidget*> widget() const;
|
||||
|
||||
void paint(QRect clip);
|
||||
|
||||
void initWindow();
|
||||
void initWidget();
|
||||
void initControls();
|
||||
void initWithCall(GroupCall *call);
|
||||
void initLayout();
|
||||
void initGeometry();
|
||||
|
||||
void handleClose();
|
||||
|
||||
void updateControlsGeometry();
|
||||
void stateChanged(State state);
|
||||
void showControls();
|
||||
void startDurationUpdateTimer(crl::time currentDuration);
|
||||
|
||||
void toggleFullScreen(bool fullscreen);
|
||||
|
||||
GroupCall *_call = nullptr;
|
||||
not_null<ChannelData*> _channel;
|
||||
|
||||
const std::unique_ptr<Ui::Window> _window;
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
std::unique_ptr<Ui::Platform::TitleControls> _controls;
|
||||
#endif // Q_OS_WIN
|
||||
|
||||
rpl::lifetime _callLifetime;
|
||||
|
||||
object_ptr<Button> _settings;
|
||||
object_ptr<Button> _hangup;
|
||||
object_ptr<Button> _mute;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Calls
|
|
@ -15,7 +15,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "lang/lang_keys.h"
|
||||
#include "boxes/confirm_box.h"
|
||||
#include "calls/calls_call.h"
|
||||
#include "calls/calls_group_call.h"
|
||||
#include "calls/calls_panel.h"
|
||||
#include "calls/calls_group_panel.h"
|
||||
#include "data/data_user.h"
|
||||
#include "data/data_group_call.h"
|
||||
#include "data/data_channel.h"
|
||||
|
@ -177,8 +179,8 @@ void Instance::createCall(not_null<UserData*> user, Call::Type type, bool video)
|
|||
|
||||
void Instance::destroyGroupCall(not_null<GroupCall*> call) {
|
||||
if (_currentGroupCall.get() == call) {
|
||||
//_currentCallPanel->closeBeforeDestroy();
|
||||
//_currentCallPanel = nullptr;
|
||||
_currentGroupCallPanel->closeBeforeDestroy();
|
||||
_currentGroupCallPanel = nullptr;
|
||||
|
||||
auto taken = base::take(_currentGroupCall);
|
||||
_currentGroupCallChanges.fire(nullptr);
|
||||
|
@ -205,6 +207,7 @@ void Instance::createGroupCall(
|
|||
destroyGroupCall(raw);
|
||||
}, raw->lifetime());
|
||||
|
||||
_currentGroupCallPanel = std::make_unique<GroupPanel>(raw);
|
||||
_currentGroupCall = std::move(call);
|
||||
_currentGroupCallChanges.fire_copy(raw);
|
||||
}
|
||||
|
@ -314,6 +317,12 @@ void Instance::showInfoPanel(not_null<Call*> call) {
|
|||
}
|
||||
}
|
||||
|
||||
void Instance::showInfoPanel(not_null<GroupCall*> call) {
|
||||
if (_currentGroupCall.get() == call) {
|
||||
_currentGroupCallPanel->showAndActivate();
|
||||
}
|
||||
}
|
||||
|
||||
bool Instance::isQuitPrevent() {
|
||||
if (!_currentCall || _currentCall->isIncomingWaiting()) {
|
||||
return false;
|
||||
|
@ -407,6 +416,7 @@ bool Instance::activateCurrentCall() {
|
|||
_currentCallPanel->showAndActivate();
|
||||
return true;
|
||||
} else if (inGroupCall()) {
|
||||
_currentGroupCallPanel->showAndActivate();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -420,6 +430,14 @@ rpl::producer<Call*> Instance::currentCallValue() const {
|
|||
return _currentCallChanges.events_starting_with(currentCall());
|
||||
}
|
||||
|
||||
GroupCall *Instance::currentGroupCall() const {
|
||||
return _currentGroupCall.get();
|
||||
}
|
||||
|
||||
rpl::producer<GroupCall*> Instance::currentGroupCallValue() const {
|
||||
return _currentGroupCallChanges.events_starting_with(currentGroupCall());
|
||||
}
|
||||
|
||||
void Instance::requestPermissionsOrFail(Fn<void()> onSuccess) {
|
||||
using Type = Platform::PermissionType;
|
||||
requestPermissionOrFail(Type::Microphone, [=] {
|
||||
|
|
|
@ -28,6 +28,7 @@ class Session;
|
|||
namespace Calls {
|
||||
|
||||
class Panel;
|
||||
class GroupPanel;
|
||||
|
||||
class Instance
|
||||
: private Call::Delegate
|
||||
|
@ -47,8 +48,11 @@ public:
|
|||
not_null<Main::Session*> session,
|
||||
const MTPUpdate &update);
|
||||
void showInfoPanel(not_null<Call*> call);
|
||||
void showInfoPanel(not_null<GroupCall*> call);
|
||||
[[nodiscard]] Call *currentCall() const;
|
||||
[[nodiscard]] rpl::producer<Call*> currentCallValue() const;
|
||||
[[nodiscard]] GroupCall *currentGroupCall() const;
|
||||
[[nodiscard]] rpl::producer<GroupCall*> currentGroupCallValue() const;
|
||||
std::shared_ptr<tgcalls::VideoCaptureInterface> getVideoCapture() override;
|
||||
|
||||
[[nodiscard]] bool isQuitPrevent();
|
||||
|
@ -117,6 +121,7 @@ private:
|
|||
|
||||
std::unique_ptr<GroupCall> _currentGroupCall;
|
||||
rpl::event_stream<GroupCall*> _currentGroupCallChanges;
|
||||
std::unique_ptr<GroupPanel> _currentGroupCallPanel;
|
||||
|
||||
std::unique_ptr<Media::Audio::Track> _callConnectingTrack;
|
||||
std::unique_ptr<Media::Audio::Track> _callEndedTrack;
|
||||
|
|
Loading…
Add table
Reference in a new issue