mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-05-24 08:43:56 +02:00
Reuse p2p call window for migrated confcall.
This commit is contained in:
parent
915dec7ba5
commit
59e56600bc
17 changed files with 606 additions and 545 deletions
|
@ -396,6 +396,8 @@ PRIVATE
|
|||
calls/calls_video_bubble.h
|
||||
calls/calls_video_incoming.cpp
|
||||
calls/calls_video_incoming.h
|
||||
calls/calls_window.cpp
|
||||
calls/calls_window.h
|
||||
chat_helpers/compose/compose_features.h
|
||||
chat_helpers/compose/compose_show.cpp
|
||||
chat_helpers/compose/compose_show.h
|
||||
|
|
|
@ -4955,7 +4955,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
"lng_confcall_invite_fail_user" = "Couldn't call {user} to join.";
|
||||
"lng_confcall_invite_fail_many#one" = "Couldn't call **{count} person** to join.";
|
||||
"lng_confcall_invite_fail_many#other" = "Couldn't call **{count} people** to join.";
|
||||
"lng_confcall_invite_kicked_user" = "{user} was removed from the call.";
|
||||
"lng_confcall_invite_kicked_user" = "{user} was banned from the call.";
|
||||
"lng_confcall_invite_kicked_many#one" = "**{count} person** was removed from the call.";
|
||||
"lng_confcall_invite_kicked_many#other" = "**{count} people** were removed from the call.";
|
||||
"lng_confcall_not_accessible" = "This call is no longer accessible.";
|
||||
|
|
|
@ -20,7 +20,7 @@ namespace GroupCalls {
|
|||
|
||||
class ListController : public PeerListController {
|
||||
public:
|
||||
explicit ListController(not_null<Window::SessionController*> window);
|
||||
explicit ListController(not_null<::Window::SessionController*> window);
|
||||
|
||||
[[nodiscard]] rpl::producer<bool> shownValue() const;
|
||||
|
||||
|
@ -30,7 +30,7 @@ public:
|
|||
void rowRightActionClicked(not_null<PeerListRow*> row) override;
|
||||
|
||||
private:
|
||||
const not_null<Window::SessionController*> _window;
|
||||
const not_null<::Window::SessionController*> _window;
|
||||
base::flat_map<PeerId, not_null<PeerListRow*>> _groupCalls;
|
||||
rpl::variable<int> _fullCount;
|
||||
|
||||
|
@ -40,7 +40,7 @@ private:
|
|||
|
||||
class BoxController : public PeerListController {
|
||||
public:
|
||||
explicit BoxController(not_null<Window::SessionController*> window);
|
||||
explicit BoxController(not_null<::Window::SessionController*> window);
|
||||
|
||||
Main::Session &session() const override;
|
||||
void prepare() override;
|
||||
|
@ -68,7 +68,7 @@ private:
|
|||
std::unique_ptr<PeerListRow> createRow(
|
||||
not_null<HistoryItem*> item) const;
|
||||
|
||||
const not_null<Window::SessionController*> _window;
|
||||
const not_null<::Window::SessionController*> _window;
|
||||
MTP::Sender _api;
|
||||
|
||||
MsgId _offsetId = 0;
|
||||
|
@ -79,6 +79,6 @@ private:
|
|||
|
||||
void ClearCallsBox(
|
||||
not_null<Ui::GenericBox*> box,
|
||||
not_null<Window::SessionController*> window);
|
||||
not_null<::Window::SessionController*> window);
|
||||
|
||||
} // namespace Calls
|
||||
|
|
|
@ -811,7 +811,7 @@ bool Call::handleUpdate(const MTPPhoneCall &call) {
|
|||
}
|
||||
if (data.is_need_rating() && _id && _accessHash) {
|
||||
const auto window = Core::App().windowFor(
|
||||
Window::SeparateId(_user));
|
||||
::Window::SeparateId(_user));
|
||||
const auto session = &_user->session();
|
||||
const auto callId = _id;
|
||||
const auto callAccessHash = _accessHash;
|
||||
|
@ -1589,7 +1589,7 @@ void Call::handleRequestError(const QString &error) {
|
|||
: error;
|
||||
if (!inform.isEmpty()) {
|
||||
if (const auto window = Core::App().windowFor(
|
||||
Window::SeparateId(_user))) {
|
||||
::Window::SeparateId(_user))) {
|
||||
window->show(Ui::MakeInformBox(inform));
|
||||
} else {
|
||||
Ui::show(Ui::MakeInformBox(inform));
|
||||
|
@ -1608,7 +1608,7 @@ void Call::handleControllerError(const QString &error) {
|
|||
: QString();
|
||||
if (!inform.isEmpty()) {
|
||||
if (const auto window = Core::App().windowFor(
|
||||
Window::SeparateId(_user))) {
|
||||
::Window::SeparateId(_user))) {
|
||||
window->show(Ui::MakeInformBox(inform));
|
||||
} else {
|
||||
Ui::show(Ui::MakeInformBox(inform));
|
||||
|
|
|
@ -153,7 +153,7 @@ std::vector<EmojiPtr> ComputeEmojiFingerprint(
|
|||
return result;
|
||||
}
|
||||
|
||||
object_ptr<Ui::RpWidget> CreateFingerprintAndSignalBars(
|
||||
base::unique_qptr<Ui::RpWidget> CreateFingerprintAndSignalBars(
|
||||
not_null<QWidget*> parent,
|
||||
not_null<Call*> call) {
|
||||
class EmojiTooltipShower final : public Ui::AbstractTooltipShower {
|
||||
|
@ -179,8 +179,8 @@ object_ptr<Ui::RpWidget> CreateFingerprintAndSignalBars(
|
|||
|
||||
};
|
||||
|
||||
auto result = object_ptr<Ui::RpWidget>(parent);
|
||||
const auto raw = result.data();
|
||||
auto result = base::make_unique_q<Ui::RpWidget>(parent);
|
||||
const auto raw = result.get();
|
||||
|
||||
// Emoji tooltip.
|
||||
const auto shower = raw->lifetime().make_state<EmojiTooltipShower>(
|
||||
|
|
|
@ -7,7 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
#include "base/object_ptr.h"
|
||||
#include "base/unique_qptr.h"
|
||||
|
||||
namespace Ui {
|
||||
class RpWidget;
|
||||
|
@ -22,7 +22,7 @@ class Call;
|
|||
[[nodiscard]] std::vector<EmojiPtr> ComputeEmojiFingerprint(
|
||||
bytes::const_span fingerprint);
|
||||
|
||||
[[nodiscard]] object_ptr<Ui::RpWidget> CreateFingerprintAndSignalBars(
|
||||
[[nodiscard]] base::unique_qptr<Ui::RpWidget> CreateFingerprintAndSignalBars(
|
||||
not_null<QWidget*> parent,
|
||||
not_null<Call*> call);
|
||||
|
||||
|
|
|
@ -349,7 +349,11 @@ void Instance::playSoundOnce(const QString &key) {
|
|||
|
||||
void Instance::destroyCall(not_null<Call*> call) {
|
||||
if (_currentCall.get() == call) {
|
||||
_currentCallPanel->closeBeforeDestroy();
|
||||
const auto groupCallWindow = _currentGroupCallPanel
|
||||
? _currentGroupCallPanel->window().get()
|
||||
: nullptr;
|
||||
const auto reused = (_currentCallPanel->window() == groupCallWindow);
|
||||
_currentCallPanel->closeBeforeDestroy(reused);
|
||||
_currentCallPanel = nullptr;
|
||||
|
||||
auto taken = base::take(_currentCall);
|
||||
|
|
|
@ -23,6 +23,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "calls/calls_userpic.h"
|
||||
#include "calls/calls_video_bubble.h"
|
||||
#include "calls/calls_video_incoming.h"
|
||||
#include "calls/calls_window.h"
|
||||
#include "ui/platform/ui_platform_window_title.h"
|
||||
#include "ui/widgets/call_button.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
|
@ -95,116 +96,49 @@ constexpr auto kHideControlsQuickTimeout = 2 * crl::time(1000);
|
|||
</svg>)";
|
||||
}
|
||||
|
||||
class Show final : public Main::SessionShow {
|
||||
public:
|
||||
explicit Show(not_null<Panel*> panel);
|
||||
~Show();
|
||||
|
||||
void showOrHideBoxOrLayer(
|
||||
std::variant<
|
||||
v::null_t,
|
||||
object_ptr<Ui::BoxContent>,
|
||||
std::unique_ptr<Ui::LayerWidget>> &&layer,
|
||||
Ui::LayerOptions options,
|
||||
anim::type animated) const override;
|
||||
[[nodiscard]] not_null<QWidget*> toastParent() const override;
|
||||
[[nodiscard]] bool valid() const override;
|
||||
operator bool() const override;
|
||||
|
||||
[[nodiscard]] Main::Session &session() const override;
|
||||
|
||||
private:
|
||||
const base::weak_ptr<Panel> _panel;
|
||||
|
||||
};
|
||||
|
||||
Show::Show(not_null<Panel*> panel)
|
||||
: _panel(base::make_weak(panel)) {
|
||||
}
|
||||
|
||||
Show::~Show() = default;
|
||||
|
||||
void Show::showOrHideBoxOrLayer(
|
||||
std::variant<
|
||||
v::null_t,
|
||||
object_ptr<Ui::BoxContent>,
|
||||
std::unique_ptr<Ui::LayerWidget>> &&layer,
|
||||
Ui::LayerOptions options,
|
||||
anim::type animated) const {
|
||||
using UniqueLayer = std::unique_ptr<Ui::LayerWidget>;
|
||||
using ObjectBox = object_ptr<Ui::BoxContent>;
|
||||
if (auto layerWidget = std::get_if<UniqueLayer>(&layer)) {
|
||||
if (const auto panel = _panel.get()) {
|
||||
panel->showLayer(std::move(*layerWidget), options, animated);
|
||||
}
|
||||
} else if (auto box = std::get_if<ObjectBox>(&layer)) {
|
||||
if (const auto panel = _panel.get()) {
|
||||
panel->showBox(std::move(*box), options, animated);
|
||||
}
|
||||
} else if (const auto panel = _panel.get()) {
|
||||
panel->hideLayer(animated);
|
||||
}
|
||||
}
|
||||
|
||||
not_null<QWidget*> Show::toastParent() const {
|
||||
const auto panel = _panel.get();
|
||||
Assert(panel != nullptr);
|
||||
return panel->widget();
|
||||
}
|
||||
|
||||
bool Show::valid() const {
|
||||
return !_panel.empty();
|
||||
}
|
||||
|
||||
Show::operator bool() const {
|
||||
return valid();
|
||||
}
|
||||
|
||||
Main::Session &Show::session() const {
|
||||
const auto panel = _panel.get();
|
||||
Assert(panel != nullptr);
|
||||
return panel->user()->session();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Panel::Panel(not_null<Call*> call)
|
||||
: _call(call)
|
||||
, _user(call->user())
|
||||
, _layerBg(std::make_unique<Ui::LayerManager>(widget()))
|
||||
#ifndef Q_OS_MAC
|
||||
, _controls(Ui::Platform::SetupSeparateTitleControls(
|
||||
window(),
|
||||
st::callTitle,
|
||||
[=](bool maximized) { toggleFullScreen(maximized); }))
|
||||
#endif // !Q_OS_MAC
|
||||
, _window(std::make_shared<Window>())
|
||||
, _bodySt(&st::callBodyLayout)
|
||||
, _answerHangupRedial(widget(), st::callAnswer, &st::callHangup)
|
||||
, _decline(widget(), object_ptr<Ui::CallButton>(widget(), st::callHangup))
|
||||
, _cancel(widget(), object_ptr<Ui::CallButton>(widget(), st::callCancel))
|
||||
, _answerHangupRedial(
|
||||
std::in_place,
|
||||
widget(),
|
||||
st::callAnswer,
|
||||
&st::callHangup)
|
||||
, _decline(
|
||||
std::in_place,
|
||||
widget(),
|
||||
object_ptr<Ui::CallButton>(widget(), st::callHangup))
|
||||
, _cancel(
|
||||
std::in_place,
|
||||
widget(),
|
||||
object_ptr<Ui::CallButton>(widget(), st::callCancel))
|
||||
, _screencast(
|
||||
std::in_place,
|
||||
widget(),
|
||||
object_ptr<Ui::CallButton>(
|
||||
widget(),
|
||||
st::callScreencastOn,
|
||||
&st::callScreencastOff))
|
||||
, _camera(widget(), st::callCameraMute, &st::callCameraUnmute)
|
||||
, _camera(std::in_place, widget(), st::callCameraMute, &st::callCameraUnmute)
|
||||
, _mute(
|
||||
std::in_place,
|
||||
widget(),
|
||||
object_ptr<Ui::CallButton>(
|
||||
widget(),
|
||||
st::callMicrophoneMute,
|
||||
&st::callMicrophoneUnmute))
|
||||
, _addPeople(
|
||||
std::in_place,
|
||||
widget(),
|
||||
object_ptr<Ui::CallButton>(widget(), st::callAddPeople))
|
||||
, _name(widget(), st::callName)
|
||||
, _status(widget(), st::callStatus)
|
||||
, _name(std::in_place, widget(), st::callName)
|
||||
, _status(std::in_place, widget(), st::callStatus)
|
||||
, _hideControlsTimer([=] { requestControlsHidden(true); })
|
||||
, _controlsShownForceTimer([=] { controlsShownForce(false); }) {
|
||||
_layerBg->setStyleOverrides(&st::groupCallBox, &st::groupCallLayerBox);
|
||||
_layerBg->setHideByBackgroundClick(true);
|
||||
|
||||
_decline->setDuration(st::callPanelDuration);
|
||||
_decline->entity()->setText(tr::lng_call_decline());
|
||||
_cancel->setDuration(st::callPanelDuration);
|
||||
|
@ -234,67 +168,15 @@ bool Panel::isActive() const {
|
|||
}
|
||||
|
||||
ConferencePanelMigration Panel::migrationInfo() const {
|
||||
const auto handle = window()->windowHandle();
|
||||
return handle ? ConferencePanelMigration{
|
||||
.screen = handle->screen(),
|
||||
.geometry = window()->geometry(),
|
||||
} : ConferencePanelMigration();
|
||||
return ConferencePanelMigration{ .window = _window };
|
||||
}
|
||||
|
||||
base::weak_ptr<Ui::Toast::Instance> Panel::showToast(
|
||||
const QString &text,
|
||||
crl::time duration) {
|
||||
return showToast({
|
||||
.text = { text },
|
||||
.duration = duration,
|
||||
});
|
||||
std::shared_ptr<Main::SessionShow> Panel::sessionShow() {
|
||||
return Main::MakeSessionShow(uiShow(), &_user->session());
|
||||
}
|
||||
|
||||
base::weak_ptr<Ui::Toast::Instance> Panel::showToast(
|
||||
TextWithEntities &&text,
|
||||
crl::time duration) {
|
||||
return showToast({
|
||||
.text = std::move(text),
|
||||
.duration = duration,
|
||||
});
|
||||
}
|
||||
|
||||
base::weak_ptr<Ui::Toast::Instance> Panel::showToast(
|
||||
Ui::Toast::Config &&config) {
|
||||
if (!config.st) {
|
||||
config.st = &st::callErrorToast;
|
||||
}
|
||||
return Show(this).showToast(std::move(config));
|
||||
}
|
||||
|
||||
void Panel::showBox(object_ptr<Ui::BoxContent> box) {
|
||||
showBox(std::move(box), Ui::LayerOption::KeepOther, anim::type::normal);
|
||||
}
|
||||
|
||||
void Panel::showBox(
|
||||
object_ptr<Ui::BoxContent> box,
|
||||
Ui::LayerOptions options,
|
||||
anim::type animated) {
|
||||
_layerBg->showBox(std::move(box), options, animated);
|
||||
}
|
||||
|
||||
void Panel::showLayer(
|
||||
std::unique_ptr<Ui::LayerWidget> layer,
|
||||
Ui::LayerOptions options,
|
||||
anim::type animated) {
|
||||
_layerBg->showLayer(std::move(layer), options, animated);
|
||||
}
|
||||
|
||||
void Panel::hideLayer(anim::type animated) {
|
||||
_layerBg->hideAll(animated);
|
||||
}
|
||||
|
||||
bool Panel::isLayerShown() const {
|
||||
return _layerBg->topShownLayer() != nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<Main::SessionShow> Panel::uiShow() {
|
||||
return std::make_shared<Show>(this);
|
||||
std::shared_ptr<Ui::Show> Panel::uiShow() {
|
||||
return _window->uiShow();
|
||||
}
|
||||
|
||||
void Panel::showAndActivate() {
|
||||
|
@ -359,20 +241,16 @@ void Panel::initWindow() {
|
|||
}
|
||||
}
|
||||
return base::EventFilterResult::Continue;
|
||||
});
|
||||
}, lifetime());
|
||||
|
||||
const auto guard = base::make_weak(this);
|
||||
window()->setBodyTitleArea([=](QPoint widgetPoint) {
|
||||
using Flag = Ui::WindowTitleHitTestFlag;
|
||||
if (!widget()->rect().contains(widgetPoint)) {
|
||||
if (!guard
|
||||
|| !widget()->rect().contains(widgetPoint)
|
||||
|| _window->controlsHasHitTest(widgetPoint)) {
|
||||
return Flag::None | Flag(0);
|
||||
}
|
||||
#ifndef Q_OS_MAC
|
||||
using Result = Ui::Platform::HitTestResult;
|
||||
const auto windowPoint = widget()->mapTo(window(), widgetPoint);
|
||||
if (_controls->controls.hitTest(windowPoint) != Result::None) {
|
||||
return Flag::None | Flag(0);
|
||||
}
|
||||
#endif // !Q_OS_MAC
|
||||
const auto buttonWidth = st::callCancel.button.width;
|
||||
const auto buttonsWidth = buttonWidth * 4;
|
||||
const auto inControls = (_fingerprint
|
||||
|
@ -387,12 +265,15 @@ void Panel::initWindow() {
|
|||
if (inControls) {
|
||||
return Flag::None | Flag(0);
|
||||
}
|
||||
const auto shown = _layerBg->topShownLayer();
|
||||
const auto shown = _window->topShownLayer();
|
||||
return (!shown || !shown->geometry().contains(widgetPoint))
|
||||
? (Flag::Move | Flag::Menu | Flag::FullScreen)
|
||||
: Flag::None;
|
||||
});
|
||||
|
||||
_window->maximizeRequests() | rpl::start_with_next([=](bool maximized) {
|
||||
toggleFullScreen(maximized);
|
||||
}, lifetime());
|
||||
// Don't do that, it looks awful :(
|
||||
//#ifdef Q_OS_WIN
|
||||
// // On Windows we replace snap-to-top maximizing with fullscreen.
|
||||
|
@ -426,12 +307,12 @@ void Panel::initWidget() {
|
|||
widget()->paintRequest(
|
||||
) | rpl::start_with_next([=](QRect clip) {
|
||||
paint(clip);
|
||||
}, widget()->lifetime());
|
||||
}, lifetime());
|
||||
|
||||
widget()->sizeValue(
|
||||
) | rpl::skip(1) | rpl::start_with_next([=] {
|
||||
updateControlsGeometry();
|
||||
}, widget()->lifetime());
|
||||
}, lifetime());
|
||||
}
|
||||
|
||||
void Panel::initControls() {
|
||||
|
@ -447,7 +328,7 @@ void Panel::initControls() {
|
|||
return;
|
||||
} else if (!env->desktopCaptureAllowed()) {
|
||||
if (auto box = Group::ScreenSharingPrivacyRequestBox()) {
|
||||
showBox(std::move(box));
|
||||
uiShow()->showBox(std::move(box));
|
||||
}
|
||||
} else if (const auto source = env->uniqueDesktopCaptureSource()) {
|
||||
if (!chooseSourceActiveDeviceId().isEmpty()) {
|
||||
|
@ -467,7 +348,7 @@ void Panel::initControls() {
|
|||
});
|
||||
_addPeople->entity()->setClickedCallback([=] {
|
||||
if (!_call || _call->state() != Call::State::Established) {
|
||||
showToast(tr::lng_call_error_add_not_started(tr::now));
|
||||
uiShow()->showToast(tr::lng_call_error_add_not_started(tr::now));
|
||||
return;
|
||||
}
|
||||
const auto call = _call;
|
||||
|
@ -484,7 +365,7 @@ void Panel::initControls() {
|
|||
*creating = true;
|
||||
const auto sharingLink = users.empty();
|
||||
Group::MakeConferenceCall({
|
||||
.show = uiShow(),
|
||||
.show = sessionShow(),
|
||||
.finished = finish,
|
||||
.joining = true,
|
||||
.info = {
|
||||
|
@ -506,7 +387,7 @@ void Panel::initControls() {
|
|||
const auto share = crl::guard(call, [=] {
|
||||
create({});
|
||||
});
|
||||
showBox(Group::PrepareInviteBox(call, invite, share));
|
||||
uiShow()->showBox(Group::PrepareInviteBox(call, invite, share));
|
||||
});
|
||||
|
||||
_updateDurationTimer.setCallback([this] {
|
||||
|
@ -559,9 +440,9 @@ void Panel::initConferenceInvite() {
|
|||
if (count < 2) {
|
||||
return;
|
||||
}
|
||||
_conferenceParticipants.create(widget());
|
||||
_conferenceParticipants = base::make_unique_q<Ui::RpWidget>(widget());
|
||||
_conferenceParticipants->show();
|
||||
const auto raw = _conferenceParticipants.data();
|
||||
const auto raw = _conferenceParticipants.get();
|
||||
|
||||
auto peers = std::vector<not_null<PeerData*>>();
|
||||
for (const auto &peer : participants) {
|
||||
|
@ -689,10 +570,9 @@ void Panel::reinitWithCall(Call *call) {
|
|||
updateControlsShown();
|
||||
});
|
||||
if (!_call) {
|
||||
_fingerprint.destroy();
|
||||
_fingerprint = nullptr;
|
||||
_incoming = nullptr;
|
||||
_outgoingVideoBubble = nullptr;
|
||||
_powerSaveBlocker = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -716,7 +596,7 @@ void Panel::reinitWithCall(Call *call) {
|
|||
if (muted) {
|
||||
createRemoteAudioMute();
|
||||
} else {
|
||||
_remoteAudioMute.destroy();
|
||||
_remoteAudioMute = nullptr;
|
||||
showRemoteLowBattery();
|
||||
}
|
||||
}, _callLifetime);
|
||||
|
@ -725,7 +605,7 @@ void Panel::reinitWithCall(Call *call) {
|
|||
if (state == Call::RemoteBatteryState::Low) {
|
||||
createRemoteLowBattery();
|
||||
} else {
|
||||
_remoteLowBattery.destroy();
|
||||
_remoteLowBattery = nullptr;
|
||||
}
|
||||
}, _callLifetime);
|
||||
_userpic = std::make_unique<Userpic>(
|
||||
|
@ -738,7 +618,7 @@ void Panel::reinitWithCall(Call *call) {
|
|||
_incoming = std::make_unique<Incoming>(
|
||||
widget(),
|
||||
_call->videoIncoming(),
|
||||
_window.backend());
|
||||
_window->backend());
|
||||
_incoming->widget()->hide();
|
||||
|
||||
_incoming->rp()->shownValue() | rpl::start_with_next([=] {
|
||||
|
@ -886,7 +766,7 @@ void Panel::reinitWithCall(Call *call) {
|
|||
}
|
||||
Unexpected("Error type in _call->errors().");
|
||||
}();
|
||||
showToast(text);
|
||||
uiShow()->showToast(text);
|
||||
}, _callLifetime);
|
||||
|
||||
_name->setText(_user->name());
|
||||
|
@ -902,16 +782,11 @@ void Panel::reinitWithCall(Call *call) {
|
|||
_mute->raise();
|
||||
_addPeople->raise();
|
||||
|
||||
_powerSaveBlocker = std::make_unique<base::PowerSaveBlocker>(
|
||||
base::PowerSaveBlockType::PreventDisplaySleep,
|
||||
u"Video call is active"_q,
|
||||
window()->windowHandle());
|
||||
|
||||
_incoming->widget()->lower();
|
||||
}
|
||||
|
||||
void Panel::createRemoteAudioMute() {
|
||||
_remoteAudioMute.create(
|
||||
_remoteAudioMute = base::make_unique_q<Ui::PaddingWrap<Ui::FlatLabel>>(
|
||||
widget(),
|
||||
object_ptr<Ui::FlatLabel>(
|
||||
widget(),
|
||||
|
@ -948,7 +823,7 @@ void Panel::createRemoteAudioMute() {
|
|||
}
|
||||
|
||||
void Panel::createRemoteLowBattery() {
|
||||
_remoteLowBattery.create(
|
||||
_remoteLowBattery = base::make_unique_q<Ui::PaddingWrap<Ui::FlatLabel>>(
|
||||
widget(),
|
||||
object_ptr<Ui::FlatLabel>(
|
||||
widget(),
|
||||
|
@ -964,7 +839,7 @@ void Panel::createRemoteLowBattery() {
|
|||
|
||||
style::PaletteChanged(
|
||||
) | rpl::start_with_next([=] {
|
||||
_remoteLowBattery.destroy();
|
||||
_remoteLowBattery = nullptr;
|
||||
createRemoteLowBattery();
|
||||
}, _remoteLowBattery->lifetime());
|
||||
|
||||
|
@ -1032,11 +907,9 @@ void Panel::initLayout() {
|
|||
}) | rpl::start_with_next([=](const Data::PeerUpdate &update) {
|
||||
_name->setText(_call->user()->name());
|
||||
updateControlsGeometry();
|
||||
}, widget()->lifetime());
|
||||
}, lifetime());
|
||||
|
||||
#ifndef Q_OS_MAC
|
||||
_controls->wrap.raise();
|
||||
#endif // !Q_OS_MAC
|
||||
_window->raiseControls();
|
||||
}
|
||||
|
||||
void Panel::showControls() {
|
||||
|
@ -1058,13 +931,16 @@ void Panel::showControls() {
|
|||
showRemoteLowBattery();
|
||||
}
|
||||
|
||||
void Panel::closeBeforeDestroy() {
|
||||
void Panel::closeBeforeDestroy(bool windowIsReused) {
|
||||
if (!windowIsReused) {
|
||||
window()->close();
|
||||
}
|
||||
reinitWithCall(nullptr);
|
||||
_lifetime.destroy();
|
||||
}
|
||||
|
||||
rpl::lifetime &Panel::lifetime() {
|
||||
return window()->lifetime();
|
||||
return _lifetime;
|
||||
}
|
||||
|
||||
void Panel::initGeometry() {
|
||||
|
@ -1202,7 +1078,7 @@ void Panel::updateControlsGeometry() {
|
|||
_controlsShown ? 1. : 0.);
|
||||
if (_fingerprint) {
|
||||
#ifndef Q_OS_MAC
|
||||
const auto controlsGeometry = _controls->controls.geometry();
|
||||
const auto controlsGeometry = _window->controlsGeometry();
|
||||
const auto halfWidth = widget()->width() / 2;
|
||||
const auto minLeft = (controlsGeometry.center().x() < halfWidth)
|
||||
? (controlsGeometry.width() + st::callFingerprintTop)
|
||||
|
@ -1391,11 +1267,11 @@ bool Panel::handleClose() const {
|
|||
}
|
||||
|
||||
not_null<Ui::RpWindow*> Panel::window() const {
|
||||
return _window.window();
|
||||
return _window->window();
|
||||
}
|
||||
|
||||
not_null<Ui::RpWidget*> Panel::widget() const {
|
||||
return _window.widget();
|
||||
return _window->widget();
|
||||
}
|
||||
|
||||
not_null<UserData*> Panel::user() const {
|
||||
|
@ -1407,17 +1283,16 @@ void Panel::stateChanged(State state) {
|
|||
|
||||
updateStatusText(state);
|
||||
|
||||
const auto isBusy = (state == State::Busy);
|
||||
const auto isWaitingUser = (state == State::WaitingUserConfirmation);
|
||||
_window->togglePowerSaveBlocker(!isBusy && !isWaitingUser);
|
||||
|
||||
if ((state != State::HangingUp)
|
||||
&& (state != State::MigrationHangingUp)
|
||||
&& (state != State::Ended)
|
||||
&& (state != State::EndedByOtherDevice)
|
||||
&& (state != State::FailedHangingUp)
|
||||
&& (state != State::Failed)) {
|
||||
const auto isBusy = (state == State::Busy);
|
||||
const auto isWaitingUser = (state == State::WaitingUserConfirmation);
|
||||
if (isBusy) {
|
||||
_powerSaveBlocker = nullptr;
|
||||
}
|
||||
if (_startVideo && !isWaitingUser) {
|
||||
_startVideo = nullptr;
|
||||
} else if (!_startVideo && isWaitingUser) {
|
||||
|
@ -1472,7 +1347,7 @@ void Panel::stateChanged(State state) {
|
|||
refreshAnswerHangupRedialLabel();
|
||||
}
|
||||
if (!_call->isKeyShaForFingerprintReady()) {
|
||||
_fingerprint.destroy();
|
||||
_fingerprint = nullptr;
|
||||
} else if (!_fingerprint) {
|
||||
_fingerprint = CreateFingerprintAndSignalBars(widget(), _call);
|
||||
updateControlsGeometry();
|
||||
|
|
|
@ -7,14 +7,9 @@ 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 "base/unique_qptr.h"
|
||||
#include "calls/calls_call.h"
|
||||
#include "calls/group/ui/desktop_capture_choose_source.h"
|
||||
#include "ui/effects/animations.h"
|
||||
#include "ui/gl/gl_window.h"
|
||||
#include "ui/rp_widget.h"
|
||||
|
||||
class Image;
|
||||
|
@ -32,6 +27,7 @@ class SessionShow;
|
|||
} // namespace Main
|
||||
|
||||
namespace Ui {
|
||||
class Show;
|
||||
class BoxContent;
|
||||
class LayerWidget;
|
||||
enum class LayerOption;
|
||||
|
@ -64,6 +60,7 @@ struct CallBodyLayout;
|
|||
|
||||
namespace Calls {
|
||||
|
||||
class Window;
|
||||
class Userpic;
|
||||
class SignalBars;
|
||||
class VideoBubble;
|
||||
|
@ -84,32 +81,11 @@ public:
|
|||
|
||||
[[nodiscard]] ConferencePanelMigration migrationInfo() const;
|
||||
|
||||
base::weak_ptr<Ui::Toast::Instance> showToast(
|
||||
const QString &text,
|
||||
crl::time duration = 0);
|
||||
base::weak_ptr<Ui::Toast::Instance> showToast(
|
||||
TextWithEntities &&text,
|
||||
crl::time duration = 0);
|
||||
base::weak_ptr<Ui::Toast::Instance> showToast(
|
||||
Ui::Toast::Config &&config);
|
||||
|
||||
void showBox(object_ptr<Ui::BoxContent> box);
|
||||
void showBox(
|
||||
object_ptr<Ui::BoxContent> box,
|
||||
Ui::LayerOptions options,
|
||||
anim::type animated = anim::type::normal);
|
||||
void showLayer(
|
||||
std::unique_ptr<Ui::LayerWidget> layer,
|
||||
Ui::LayerOptions options,
|
||||
anim::type animated = anim::type::normal);
|
||||
void hideLayer(anim::type animated = anim::type::normal);
|
||||
[[nodiscard]] bool isLayerShown() const;
|
||||
|
||||
void showAndActivate();
|
||||
void minimize();
|
||||
void toggleFullScreen();
|
||||
void replaceCall(not_null<Call*> call);
|
||||
void closeBeforeDestroy();
|
||||
void closeBeforeDestroy(bool windowIsReused = false);
|
||||
|
||||
QWidget *chooseSourceParent() override;
|
||||
QString chooseSourceActiveDeviceId() override;
|
||||
|
@ -123,7 +99,10 @@ public:
|
|||
|
||||
[[nodiscard]] rpl::producer<bool> startOutgoingRequests() const;
|
||||
|
||||
[[nodiscard]] std::shared_ptr<Main::SessionShow> uiShow();
|
||||
[[nodiscard]] std::shared_ptr<Main::SessionShow> sessionShow();
|
||||
[[nodiscard]] std::shared_ptr<Ui::Show> uiShow();
|
||||
|
||||
[[nodiscard]] not_null<Ui::RpWindow*> window() const;
|
||||
|
||||
[[nodiscard]] rpl::lifetime &lifetime();
|
||||
|
||||
|
@ -138,8 +117,6 @@ private:
|
|||
StartCall,
|
||||
};
|
||||
|
||||
[[nodiscard]] not_null<Ui::RpWindow*> window() const;
|
||||
|
||||
void paint(QRect clip);
|
||||
|
||||
void initWindow();
|
||||
|
@ -184,43 +161,35 @@ private:
|
|||
Call *_call = nullptr;
|
||||
not_null<UserData*> _user;
|
||||
|
||||
Ui::GL::Window _window;
|
||||
const std::unique_ptr<Ui::LayerManager> _layerBg;
|
||||
std::shared_ptr<Window> _window;
|
||||
std::unique_ptr<Incoming> _incoming;
|
||||
|
||||
#ifndef Q_OS_MAC
|
||||
std::unique_ptr<Ui::Platform::SeparateTitleControls> _controls;
|
||||
#endif // !Q_OS_MAC
|
||||
|
||||
std::unique_ptr<base::PowerSaveBlocker> _powerSaveBlocker;
|
||||
|
||||
QSize _incomingFrameSize;
|
||||
|
||||
rpl::lifetime _callLifetime;
|
||||
|
||||
not_null<const style::CallBodyLayout*> _bodySt;
|
||||
object_ptr<Ui::CallButton> _answerHangupRedial;
|
||||
object_ptr<Ui::FadeWrap<Ui::CallButton>> _decline;
|
||||
object_ptr<Ui::FadeWrap<Ui::CallButton>> _cancel;
|
||||
base::unique_qptr<Ui::CallButton> _answerHangupRedial;
|
||||
base::unique_qptr<Ui::FadeWrap<Ui::CallButton>> _decline;
|
||||
base::unique_qptr<Ui::FadeWrap<Ui::CallButton>> _cancel;
|
||||
bool _hangupShown = false;
|
||||
bool _conferenceSupported = false;
|
||||
bool _outgoingPreviewInBody = false;
|
||||
std::optional<AnswerHangupRedialState> _answerHangupRedialState;
|
||||
Ui::Animations::Simple _hangupShownProgress;
|
||||
object_ptr<Ui::FadeWrap<Ui::CallButton>> _screencast;
|
||||
object_ptr<Ui::CallButton> _camera;
|
||||
base::unique_qptr<Ui::FadeWrap<Ui::CallButton>> _screencast;
|
||||
base::unique_qptr<Ui::CallButton> _camera;
|
||||
Ui::CallButton *_cameraDeviceToggle = nullptr;
|
||||
base::unique_qptr<Ui::CallButton> _startVideo;
|
||||
object_ptr<Ui::FadeWrap<Ui::CallButton>> _mute;
|
||||
base::unique_qptr<Ui::FadeWrap<Ui::CallButton>> _mute;
|
||||
Ui::CallButton *_audioDeviceToggle = nullptr;
|
||||
object_ptr < Ui::FadeWrap<Ui::CallButton>> _addPeople;
|
||||
object_ptr<Ui::FlatLabel> _name;
|
||||
object_ptr<Ui::FlatLabel> _status;
|
||||
object_ptr<Ui::RpWidget> _conferenceParticipants = { nullptr };
|
||||
object_ptr<Ui::RpWidget> _fingerprint = { nullptr };
|
||||
object_ptr<Ui::PaddingWrap<Ui::FlatLabel>> _remoteAudioMute = { nullptr };
|
||||
object_ptr<Ui::PaddingWrap<Ui::FlatLabel>> _remoteLowBattery
|
||||
= { nullptr };
|
||||
base::unique_qptr<Ui::FadeWrap<Ui::CallButton>> _addPeople;
|
||||
base::unique_qptr<Ui::FlatLabel> _name;
|
||||
base::unique_qptr<Ui::FlatLabel> _status;
|
||||
base::unique_qptr<Ui::RpWidget> _conferenceParticipants;
|
||||
base::unique_qptr<Ui::RpWidget> _fingerprint;
|
||||
base::unique_qptr<Ui::PaddingWrap<Ui::FlatLabel>> _remoteAudioMute;
|
||||
base::unique_qptr<Ui::PaddingWrap<Ui::FlatLabel>> _remoteLowBattery;
|
||||
std::unique_ptr<Userpic> _userpic;
|
||||
std::unique_ptr<VideoBubble> _outgoingVideoBubble;
|
||||
QPixmap _bottomShadow;
|
||||
|
@ -245,6 +214,8 @@ private:
|
|||
|
||||
rpl::event_stream<bool> _startOutgoingRequests;
|
||||
|
||||
rpl::lifetime _lifetime;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Calls
|
||||
|
|
250
Telegram/SourceFiles/calls/calls_window.cpp
Normal file
250
Telegram/SourceFiles/calls/calls_window.cpp
Normal file
|
@ -0,0 +1,250 @@
|
|||
/*
|
||||
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_window.h"
|
||||
|
||||
#include "base/power_save_blocker.h"
|
||||
#include "ui/platform/ui_platform_window_title.h"
|
||||
#include "ui/widgets/rp_window.h"
|
||||
#include "ui/layers/layer_manager.h"
|
||||
#include "ui/layers/show.h"
|
||||
#include "styles/style_calls.h"
|
||||
|
||||
namespace Calls {
|
||||
namespace {
|
||||
|
||||
class Show final : public Ui::Show {
|
||||
public:
|
||||
explicit Show(not_null<Window*> window);
|
||||
~Show();
|
||||
|
||||
void showOrHideBoxOrLayer(
|
||||
std::variant<
|
||||
v::null_t,
|
||||
object_ptr<Ui::BoxContent>,
|
||||
std::unique_ptr<Ui::LayerWidget>> &&layer,
|
||||
Ui::LayerOptions options,
|
||||
anim::type animated) const override;
|
||||
[[nodiscard]] not_null<QWidget*> toastParent() const override;
|
||||
[[nodiscard]] bool valid() const override;
|
||||
operator bool() const override;
|
||||
|
||||
private:
|
||||
const base::weak_ptr<Window> _window;
|
||||
|
||||
};
|
||||
|
||||
Show::Show(not_null<Window*> window)
|
||||
: _window(base::make_weak(window)) {
|
||||
}
|
||||
|
||||
Show::~Show() = default;
|
||||
|
||||
void Show::showOrHideBoxOrLayer(
|
||||
std::variant<
|
||||
v::null_t,
|
||||
object_ptr<Ui::BoxContent>,
|
||||
std::unique_ptr<Ui::LayerWidget>> &&layer,
|
||||
Ui::LayerOptions options,
|
||||
anim::type animated) const {
|
||||
using UniqueLayer = std::unique_ptr<Ui::LayerWidget>;
|
||||
using ObjectBox = object_ptr<Ui::BoxContent>;
|
||||
if (auto layerWidget = std::get_if<UniqueLayer>(&layer)) {
|
||||
if (const auto window = _window.get()) {
|
||||
window->showLayer(std::move(*layerWidget), options, animated);
|
||||
}
|
||||
} else if (auto box = std::get_if<ObjectBox>(&layer)) {
|
||||
if (const auto window = _window.get()) {
|
||||
window->showBox(std::move(*box), options, animated);
|
||||
}
|
||||
} else if (const auto window = _window.get()) {
|
||||
window->hideLayer(animated);
|
||||
}
|
||||
}
|
||||
|
||||
not_null<QWidget*> Show::toastParent() const {
|
||||
const auto window = _window.get();
|
||||
Assert(window != nullptr);
|
||||
return window->widget();
|
||||
}
|
||||
|
||||
bool Show::valid() const {
|
||||
return !_window.empty();
|
||||
}
|
||||
|
||||
Show::operator bool() const {
|
||||
return valid();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Window::Window()
|
||||
: _layerBg(std::make_unique<Ui::LayerManager>(widget()))
|
||||
#ifndef Q_OS_MAC
|
||||
, _controls(Ui::Platform::SetupSeparateTitleControls(
|
||||
window(),
|
||||
st::callTitle,
|
||||
[=](bool maximized) { _maximizeRequests.fire_copy(maximized); },
|
||||
_controlsTop.value()))
|
||||
#endif // !Q_OS_MAC
|
||||
{
|
||||
_layerBg->setStyleOverrides(&st::groupCallBox, &st::groupCallLayerBox);
|
||||
_layerBg->setHideByBackgroundClick(true);
|
||||
}
|
||||
|
||||
Window::~Window() = default;
|
||||
|
||||
Ui::GL::Backend Window::backend() const {
|
||||
return _window.backend();
|
||||
}
|
||||
|
||||
not_null<Ui::RpWindow*> Window::window() const {
|
||||
return _window.window();
|
||||
}
|
||||
|
||||
not_null<Ui::RpWidget*> Window::widget() const {
|
||||
return _window.widget();
|
||||
}
|
||||
|
||||
void Window::raiseControls() {
|
||||
#ifndef Q_OS_MAC
|
||||
_controls->wrap.raise();
|
||||
#endif // !Q_OS_MAC
|
||||
}
|
||||
|
||||
void Window::setControlsStyle(const style::WindowTitle &st) {
|
||||
#ifndef Q_OS_MAC
|
||||
_controls->controls.setStyle(st);
|
||||
#endif // Q_OS_MAC
|
||||
}
|
||||
|
||||
void Window::setControlsShown(float64 shown) {
|
||||
#ifndef Q_OS_MAC
|
||||
_controlsTop = anim::interpolate(-_controls->wrap.height(), 0, shown);
|
||||
#endif // Q_OS_MAC
|
||||
}
|
||||
|
||||
int Window::controlsWrapTop() const {
|
||||
#ifndef Q_OS_MAC
|
||||
return _controls->wrap.y();
|
||||
#else // Q_OS_MAC
|
||||
return 0;
|
||||
#endif // Q_OS_MAC
|
||||
}
|
||||
|
||||
QRect Window::controlsGeometry() const {
|
||||
#ifndef Q_OS_MAC
|
||||
return _controls->controls.geometry();
|
||||
#else // Q_OS_MAC
|
||||
return QRect();
|
||||
#endif // Q_OS_MAC
|
||||
}
|
||||
|
||||
auto Window::controlsLayoutChanges() const
|
||||
-> rpl::producer<Ui::Platform::TitleLayout> {
|
||||
#ifndef Q_OS_MAC
|
||||
return _controls->controls.layout().changes();
|
||||
#else // Q_OS_MAC
|
||||
return rpl::never<Ui::Platform::TitleLayout>();
|
||||
#endif // Q_OS_MAC
|
||||
}
|
||||
|
||||
bool Window::controlsHasHitTest(QPoint widgetPoint) const {
|
||||
#ifndef Q_OS_MAC
|
||||
using Result = Ui::Platform::HitTestResult;
|
||||
const auto windowPoint = widget()->mapTo(window(), widgetPoint);
|
||||
return (_controls->controls.hitTest(windowPoint) != Result::None);
|
||||
#else // Q_OS_MAC
|
||||
return false;
|
||||
#endif // Q_OS_MAC
|
||||
}
|
||||
|
||||
rpl::producer<bool> Window::maximizeRequests() const {
|
||||
return _maximizeRequests.events();
|
||||
}
|
||||
|
||||
base::weak_ptr<Ui::Toast::Instance> Window::showToast(
|
||||
const QString &text,
|
||||
crl::time duration) {
|
||||
return Show(this).showToast(text, duration);
|
||||
}
|
||||
|
||||
base::weak_ptr<Ui::Toast::Instance> Window::showToast(
|
||||
TextWithEntities &&text,
|
||||
crl::time duration) {
|
||||
return Show(this).showToast(std::move(text), duration);
|
||||
}
|
||||
|
||||
base::weak_ptr<Ui::Toast::Instance> Window::showToast(
|
||||
Ui::Toast::Config &&config) {
|
||||
return Show(this).showToast(std::move(config));
|
||||
}
|
||||
|
||||
void Window::raiseLayers() {
|
||||
_layerBg->raise();
|
||||
}
|
||||
|
||||
const Ui::LayerWidget *Window::topShownLayer() const {
|
||||
return _layerBg->topShownLayer();
|
||||
}
|
||||
|
||||
void Window::showBox(object_ptr<Ui::BoxContent> box) {
|
||||
showBox(std::move(box), Ui::LayerOption::KeepOther, anim::type::normal);
|
||||
}
|
||||
|
||||
void Window::showBox(
|
||||
object_ptr<Ui::BoxContent> box,
|
||||
Ui::LayerOptions options,
|
||||
anim::type animated) {
|
||||
_showingLayer.fire({});
|
||||
if (window()->width() < st::groupCallWidth
|
||||
|| window()->height() < st::groupCallWidth) {
|
||||
window()->resize(
|
||||
std::max(window()->width(), st::groupCallWidth),
|
||||
std::max(window()->height(), st::groupCallWidth));
|
||||
}
|
||||
_layerBg->showBox(std::move(box), options, animated);
|
||||
}
|
||||
|
||||
void Window::showLayer(
|
||||
std::unique_ptr<Ui::LayerWidget> layer,
|
||||
Ui::LayerOptions options,
|
||||
anim::type animated) {
|
||||
_showingLayer.fire({});
|
||||
if (window()->width() < st::groupCallWidth
|
||||
|| window()->height() < st::groupCallWidth) {
|
||||
window()->resize(
|
||||
std::max(window()->width(), st::groupCallWidth),
|
||||
std::max(window()->height(), st::groupCallWidth));
|
||||
}
|
||||
_layerBg->showLayer(std::move(layer), options, animated);
|
||||
}
|
||||
|
||||
void Window::hideLayer(anim::type animated) {
|
||||
_layerBg->hideAll(animated);
|
||||
}
|
||||
|
||||
bool Window::isLayerShown() const {
|
||||
return _layerBg->topShownLayer() != nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<Ui::Show> Window::uiShow() {
|
||||
return std::make_shared<Show>(this);
|
||||
}
|
||||
|
||||
void Window::togglePowerSaveBlocker(bool enabled) {
|
||||
if (!enabled) {
|
||||
_powerSaveBlocker = nullptr;
|
||||
} else if (!_powerSaveBlocker) {
|
||||
_powerSaveBlocker = std::make_unique<base::PowerSaveBlocker>(
|
||||
base::PowerSaveBlockType::PreventDisplaySleep,
|
||||
u"Video call is active"_q,
|
||||
window()->windowHandle());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Calls
|
112
Telegram/SourceFiles/calls/calls_window.h
Normal file
112
Telegram/SourceFiles/calls/calls_window.h
Normal file
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
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/object_ptr.h"
|
||||
#include "ui/effects/animations.h"
|
||||
#include "ui/gl/gl_window.h"
|
||||
|
||||
namespace base {
|
||||
class PowerSaveBlocker;
|
||||
} // namespace base
|
||||
|
||||
namespace style {
|
||||
struct WindowTitle;
|
||||
} // namespace style
|
||||
|
||||
namespace Ui {
|
||||
class BoxContent;
|
||||
class RpWindow;
|
||||
class RpWidget;
|
||||
class LayerManager;
|
||||
class LayerWidget;
|
||||
enum class LayerOption;
|
||||
using LayerOptions = base::flags<LayerOption>;
|
||||
class Show;
|
||||
} // namespace Ui
|
||||
|
||||
namespace Ui::Platform {
|
||||
struct SeparateTitleControls;
|
||||
struct TitleLayout;
|
||||
} // namespace Ui::Platform
|
||||
|
||||
namespace Ui::Toast {
|
||||
struct Config;
|
||||
class Instance;
|
||||
} // namespace Ui::Toast
|
||||
|
||||
namespace Calls {
|
||||
|
||||
class Window final : public base::has_weak_ptr {
|
||||
public:
|
||||
Window();
|
||||
~Window();
|
||||
|
||||
[[nodiscard]] Ui::GL::Backend backend() const;
|
||||
[[nodiscard]] not_null<Ui::RpWindow*> window() const;
|
||||
[[nodiscard]] not_null<Ui::RpWidget*> widget() const;
|
||||
|
||||
void raiseControls();
|
||||
void setControlsStyle(const style::WindowTitle &st);
|
||||
void setControlsShown(float64 shown);
|
||||
[[nodiscard]] int controlsWrapTop() const;
|
||||
[[nodiscard]] QRect controlsGeometry() const;
|
||||
[[nodiscard]] auto controlsLayoutChanges() const
|
||||
-> rpl::producer<Ui::Platform::TitleLayout>;
|
||||
[[nodiscard]] bool controlsHasHitTest(QPoint widgetPoint) const;
|
||||
[[nodiscard]] rpl::producer<bool> maximizeRequests() const;
|
||||
|
||||
void raiseLayers();
|
||||
[[nodiscard]] const Ui::LayerWidget *topShownLayer() const;
|
||||
|
||||
base::weak_ptr<Ui::Toast::Instance> showToast(
|
||||
const QString &text,
|
||||
crl::time duration = 0);
|
||||
base::weak_ptr<Ui::Toast::Instance> showToast(
|
||||
TextWithEntities &&text,
|
||||
crl::time duration = 0);
|
||||
base::weak_ptr<Ui::Toast::Instance> showToast(
|
||||
Ui::Toast::Config &&config);
|
||||
|
||||
void showBox(object_ptr<Ui::BoxContent> box);
|
||||
void showBox(
|
||||
object_ptr<Ui::BoxContent> box,
|
||||
Ui::LayerOptions options,
|
||||
anim::type animated = anim::type::normal);
|
||||
void showLayer(
|
||||
std::unique_ptr<Ui::LayerWidget> layer,
|
||||
Ui::LayerOptions options,
|
||||
anim::type animated = anim::type::normal);
|
||||
void hideLayer(anim::type animated = anim::type::normal);
|
||||
[[nodiscard]] bool isLayerShown() const;
|
||||
|
||||
[[nodiscard]] rpl::producer<> showingLayer() const {
|
||||
return _showingLayer.events();
|
||||
}
|
||||
|
||||
[[nodiscard]] std::shared_ptr<Ui::Show> uiShow();
|
||||
|
||||
void togglePowerSaveBlocker(bool enabled);
|
||||
|
||||
private:
|
||||
Ui::GL::Window _window;
|
||||
const std::unique_ptr<Ui::LayerManager> _layerBg;
|
||||
|
||||
#ifndef Q_OS_MAC
|
||||
rpl::variable<int> _controlsTop = 0;
|
||||
const std::unique_ptr<Ui::Platform::SeparateTitleControls> _controls;
|
||||
#endif // !Q_OS_MAC
|
||||
|
||||
std::unique_ptr<base::PowerSaveBlocker> _powerSaveBlocker;
|
||||
|
||||
rpl::event_stream<bool> _maximizeRequests;
|
||||
rpl::event_stream<> _showingLayer;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Calls
|
|
@ -48,6 +48,8 @@ class SessionController;
|
|||
|
||||
namespace Calls {
|
||||
|
||||
class Window;
|
||||
|
||||
struct InviteRequest {
|
||||
not_null<UserData*> user;
|
||||
bool video = false;
|
||||
|
@ -75,8 +77,7 @@ struct StartConferenceInfo {
|
|||
};
|
||||
|
||||
struct ConferencePanelMigration {
|
||||
QScreen *screen = nullptr;
|
||||
QRect geometry;
|
||||
std::shared_ptr<Window> window;
|
||||
};
|
||||
|
||||
} // namespace Calls
|
||||
|
|
|
@ -1359,22 +1359,22 @@ base::unique_qptr<Ui::PopupMenu> Members::Controller::createRowContextMenu(
|
|||
window->invokeForSessionController(
|
||||
account,
|
||||
participantPeer,
|
||||
[&](not_null<Window::SessionController*> newController) {
|
||||
[&](not_null<::Window::SessionController*> newController) {
|
||||
callback(newController);
|
||||
newController->widget()->activate();
|
||||
});
|
||||
}
|
||||
};
|
||||
const auto showProfile = [=] {
|
||||
withActiveWindow([=](not_null<Window::SessionController*> window) {
|
||||
withActiveWindow([=](not_null<::Window::SessionController*> window) {
|
||||
window->showPeerInfo(participantPeer);
|
||||
});
|
||||
};
|
||||
const auto showHistory = [=] {
|
||||
withActiveWindow([=](not_null<Window::SessionController*> window) {
|
||||
withActiveWindow([=](not_null<::Window::SessionController*> window) {
|
||||
window->showPeerHistory(
|
||||
participantPeer,
|
||||
Window::SectionShow::Way::Forward);
|
||||
::Window::SectionShow::Way::Forward);
|
||||
});
|
||||
};
|
||||
const auto removeFromVoiceChat = crl::guard(this, [=] {
|
||||
|
|
|
@ -17,7 +17,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "calls/group/ui/calls_group_scheduled_labels.h"
|
||||
#include "calls/group/ui/desktop_capture_choose_source.h"
|
||||
#include "calls/calls_emoji_fingerprint.h"
|
||||
#include "ui/platform/ui_platform_window_title.h"
|
||||
#include "calls/calls_window.h"
|
||||
#include "ui/platform/ui_platform_window_title.h" // TitleLayout
|
||||
#include "ui/platform/ui_platform_utility.h"
|
||||
#include "ui/controls/call_mute_button.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
|
@ -29,7 +30,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/widgets/rp_window.h"
|
||||
#include "ui/chat/group_call_bar.h"
|
||||
#include "ui/controls/userpic_button.h"
|
||||
#include "ui/layers/layer_manager.h"
|
||||
#include "ui/layers/generic_box.h"
|
||||
#include "ui/text/text_utilities.h"
|
||||
#include "ui/toast/toast.h"
|
||||
|
@ -54,7 +54,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "base/unixtime.h"
|
||||
#include "base/qt_signal_producer.h"
|
||||
#include "base/timer_rpl.h"
|
||||
#include "base/power_save_blocker.h"
|
||||
#include "apiwrap.h" // api().kick.
|
||||
#include "api/api_chat_participants.h" // api().kick.
|
||||
#include "webrtc/webrtc_environment.h"
|
||||
|
@ -91,77 +90,6 @@ constexpr auto kHideControlsTimeout = 5 * crl::time(1000);
|
|||
return result;
|
||||
}
|
||||
|
||||
class Show final : public Main::SessionShow {
|
||||
public:
|
||||
explicit Show(not_null<Panel*> panel);
|
||||
~Show();
|
||||
|
||||
void showOrHideBoxOrLayer(
|
||||
std::variant<
|
||||
v::null_t,
|
||||
object_ptr<Ui::BoxContent>,
|
||||
std::unique_ptr<Ui::LayerWidget>> &&layer,
|
||||
Ui::LayerOptions options,
|
||||
anim::type animated) const override;
|
||||
[[nodiscard]] not_null<QWidget*> toastParent() const override;
|
||||
[[nodiscard]] bool valid() const override;
|
||||
operator bool() const override;
|
||||
|
||||
[[nodiscard]] Main::Session &session() const override;
|
||||
|
||||
private:
|
||||
const base::weak_ptr<Panel> _panel;
|
||||
|
||||
};
|
||||
|
||||
Show::Show(not_null<Panel*> panel)
|
||||
: _panel(base::make_weak(panel)) {
|
||||
}
|
||||
|
||||
Show::~Show() = default;
|
||||
|
||||
void Show::showOrHideBoxOrLayer(
|
||||
std::variant<
|
||||
v::null_t,
|
||||
object_ptr<Ui::BoxContent>,
|
||||
std::unique_ptr<Ui::LayerWidget>> &&layer,
|
||||
Ui::LayerOptions options,
|
||||
anim::type animated) const {
|
||||
using UniqueLayer = std::unique_ptr<Ui::LayerWidget>;
|
||||
using ObjectBox = object_ptr<Ui::BoxContent>;
|
||||
if (auto layerWidget = std::get_if<UniqueLayer>(&layer)) {
|
||||
if (const auto panel = _panel.get()) {
|
||||
panel->showLayer(std::move(*layerWidget), options, animated);
|
||||
}
|
||||
} else if (auto box = std::get_if<ObjectBox>(&layer)) {
|
||||
if (const auto panel = _panel.get()) {
|
||||
panel->showBox(std::move(*box), options, animated);
|
||||
}
|
||||
} else if (const auto panel = _panel.get()) {
|
||||
panel->hideLayer(animated);
|
||||
}
|
||||
}
|
||||
|
||||
not_null<QWidget*> Show::toastParent() const {
|
||||
const auto panel = _panel.get();
|
||||
Assert(panel != nullptr);
|
||||
return panel->widget();
|
||||
}
|
||||
|
||||
bool Show::valid() const {
|
||||
return !_panel.empty();
|
||||
}
|
||||
|
||||
Show::operator bool() const {
|
||||
return valid();
|
||||
}
|
||||
|
||||
Main::Session &Show::session() const {
|
||||
const auto panel = _panel.get();
|
||||
Assert(panel != nullptr);
|
||||
return panel->call()->peer()->session();
|
||||
}
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
void UnpinMaximized(not_null<QWidget*> widget) {
|
||||
SetWindowPos(
|
||||
|
@ -198,20 +126,12 @@ Panel::Panel(not_null<GroupCall*> call)
|
|||
Panel::Panel(not_null<GroupCall*> call, ConferencePanelMigration info)
|
||||
: _call(call)
|
||||
, _peer(call->peer())
|
||||
, _layerBg(std::make_unique<Ui::LayerManager>(widget()))
|
||||
#ifndef Q_OS_MAC
|
||||
, _controls(Ui::Platform::SetupSeparateTitleControls(
|
||||
window(),
|
||||
st::groupCallTitle,
|
||||
nullptr,
|
||||
_controlsTop.value()))
|
||||
#endif // !Q_OS_MAC
|
||||
, _powerSaveBlocker(std::make_unique<base::PowerSaveBlocker>(
|
||||
base::PowerSaveBlockType::PreventDisplaySleep,
|
||||
u"Video chat is active"_q,
|
||||
window()->windowHandle()))
|
||||
, _window(info.window ? info.window : std::make_shared<Window>())
|
||||
, _viewport(
|
||||
std::make_unique<Viewport>(widget(), PanelMode::Wide, _window.backend()))
|
||||
std::make_unique<Viewport>(
|
||||
widget(),
|
||||
PanelMode::Wide,
|
||||
_window->backend()))
|
||||
, _mute(std::make_unique<Ui::CallMuteButton>(
|
||||
widget(),
|
||||
st::callMuteButton,
|
||||
|
@ -241,9 +161,6 @@ Panel::Panel(not_null<GroupCall*> call, ConferencePanelMigration info)
|
|||
return result;
|
||||
})
|
||||
, _hideControlsTimer([=] { toggleWideControls(false); }) {
|
||||
_layerBg->setStyleOverrides(&st::groupCallBox, &st::groupCallLayerBox);
|
||||
_layerBg->setHideByBackgroundClick(true);
|
||||
|
||||
_viewport->widget()->hide();
|
||||
if (!_viewport->requireARGB32()) {
|
||||
_call->setNotRequireARGB32();
|
||||
|
@ -287,25 +204,12 @@ bool Panel::isActive() const {
|
|||
return window()->isActiveWindow() && isVisible();
|
||||
}
|
||||
|
||||
base::weak_ptr<Ui::Toast::Instance> Panel::showToast(
|
||||
const QString &text,
|
||||
crl::time duration) {
|
||||
return Show(this).showToast(text, duration);
|
||||
std::shared_ptr<Main::SessionShow> Panel::sessionShow() {
|
||||
return Main::MakeSessionShow(uiShow(), &_peer->session());
|
||||
}
|
||||
|
||||
base::weak_ptr<Ui::Toast::Instance> Panel::showToast(
|
||||
TextWithEntities &&text,
|
||||
crl::time duration) {
|
||||
return Show(this).showToast(std::move(text), duration);
|
||||
}
|
||||
|
||||
base::weak_ptr<Ui::Toast::Instance> Panel::showToast(
|
||||
Ui::Toast::Config &&config) {
|
||||
return Show(this).showToast(std::move(config));
|
||||
}
|
||||
|
||||
std::shared_ptr<Main::SessionShow> Panel::uiShow() {
|
||||
return std::make_shared<Show>(this);
|
||||
std::shared_ptr<Ui::Show> Panel::uiShow() {
|
||||
return _window->uiShow();
|
||||
}
|
||||
|
||||
void Panel::minimize() {
|
||||
|
@ -394,12 +298,20 @@ void Panel::initWindow() {
|
|||
subscribeToPeerChanges();
|
||||
}
|
||||
|
||||
const auto updateFullScreen = [=] {
|
||||
const auto state = window()->windowState();
|
||||
const auto full = (state & Qt::WindowFullScreen)
|
||||
|| (state & Qt::WindowMaximized);
|
||||
_rtmpFull = _call->rtmp() && full;
|
||||
_fullScreenOrMaximized = full;
|
||||
};
|
||||
base::install_event_filter(window().get(), [=](not_null<QEvent*> e) {
|
||||
if (e->type() == QEvent::Close && handleClose()) {
|
||||
const auto type = e->type();
|
||||
if (type == QEvent::Close && handleClose()) {
|
||||
e->ignore();
|
||||
return base::EventFilterResult::Cancel;
|
||||
} else if (e->type() == QEvent::KeyPress
|
||||
|| e->type() == QEvent::KeyRelease) {
|
||||
} else if (_call->rtmp()
|
||||
&& (type == QEvent::KeyPress || type == QEvent::KeyRelease)) {
|
||||
const auto key = static_cast<QKeyEvent*>(e.get())->key();
|
||||
if (key == Qt::Key_Space) {
|
||||
_call->pushToTalk(
|
||||
|
@ -409,16 +321,19 @@ void Panel::initWindow() {
|
|||
&& _fullScreenOrMaximized.current()) {
|
||||
toggleFullScreen();
|
||||
}
|
||||
} else if (e->type() == QEvent::WindowStateChange && _call->rtmp()) {
|
||||
const auto state = window()->windowState();
|
||||
_fullScreenOrMaximized = (state & Qt::WindowFullScreen)
|
||||
|| (state & Qt::WindowMaximized);
|
||||
} else if (type == QEvent::WindowStateChange) {
|
||||
updateFullScreen();
|
||||
}
|
||||
return base::EventFilterResult::Continue;
|
||||
});
|
||||
}, lifetime());
|
||||
updateFullScreen();
|
||||
|
||||
const auto guard = base::make_weak(this);
|
||||
window()->setBodyTitleArea([=](QPoint widgetPoint) {
|
||||
using Flag = Ui::WindowTitleHitTestFlag;
|
||||
if (!guard) {
|
||||
return (Flag::None | Flag(0));
|
||||
}
|
||||
const auto titleRect = QRect(
|
||||
0,
|
||||
0,
|
||||
|
@ -434,7 +349,7 @@ void Panel::initWindow() {
|
|||
if (!moveable) {
|
||||
return (Flag::None | Flag(0));
|
||||
}
|
||||
const auto shown = _layerBg->topShownLayer();
|
||||
const auto shown = _window->topShownLayer();
|
||||
return (!shown || !shown->geometry().contains(widgetPoint))
|
||||
? (Flag::Move | Flag::Menu | Flag::Maximize)
|
||||
: Flag::None;
|
||||
|
@ -444,6 +359,23 @@ void Panel::initWindow() {
|
|||
) | rpl::start_with_next([=] {
|
||||
updateMode();
|
||||
}, lifetime());
|
||||
|
||||
_window->maximizeRequests() | rpl::start_with_next([=](bool maximized) {
|
||||
if (_call->rtmp()) {
|
||||
toggleFullScreen(maximized);
|
||||
} else {
|
||||
window()->setWindowState(maximized
|
||||
? Qt::WindowMaximized
|
||||
: Qt::WindowNoState);
|
||||
}
|
||||
}, lifetime());
|
||||
|
||||
_window->showingLayer() | rpl::start_with_next([=] {
|
||||
hideStickedTooltip(StickedTooltipHide::Unavailable);
|
||||
}, lifetime());
|
||||
|
||||
_window->setControlsStyle(st::groupCallTitle);
|
||||
_window->togglePowerSaveBlocker(true);
|
||||
}
|
||||
|
||||
void Panel::initWidget() {
|
||||
|
@ -462,7 +394,7 @@ void Panel::initWidget() {
|
|||
|
||||
// some geometries depends on _controls->controls.geometry,
|
||||
// which is not updated here yet.
|
||||
crl::on_main(widget(), [=] { updateControlsGeometry(); });
|
||||
crl::on_main(this, [=] { updateControlsGeometry(); });
|
||||
}, lifetime());
|
||||
}
|
||||
|
||||
|
@ -471,7 +403,7 @@ void Panel::endCall() {
|
|||
_call->hangup();
|
||||
return;
|
||||
}
|
||||
showBox(Box(
|
||||
uiShow()->showBox(Box(
|
||||
LeaveBox,
|
||||
_call,
|
||||
false,
|
||||
|
@ -501,7 +433,7 @@ void Panel::startScheduledNow() {
|
|||
.confirmText = tr::lng_group_call_start_now(),
|
||||
});
|
||||
*box = owned.data();
|
||||
showBox(std::move(owned));
|
||||
uiShow()->showBox(std::move(owned));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -608,10 +540,15 @@ void Panel::initControls() {
|
|||
}
|
||||
|
||||
void Panel::toggleFullScreen() {
|
||||
if (_fullScreenOrMaximized.current() || window()->isFullScreen()) {
|
||||
window()->showNormal();
|
||||
} else {
|
||||
toggleFullScreen(
|
||||
!_fullScreenOrMaximized.current() && !window()->isFullScreen());
|
||||
}
|
||||
|
||||
void Panel::toggleFullScreen(bool fullscreen) {
|
||||
if (fullscreen) {
|
||||
window()->showFullScreen();
|
||||
} else {
|
||||
window()->showNormal();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -630,7 +567,7 @@ void Panel::refreshLeftButton() {
|
|||
_callShare.destroy();
|
||||
_settings.create(widget(), st::groupCallSettings);
|
||||
_settings->setClickedCallback([=] {
|
||||
showBox(Box(SettingsBox, _call));
|
||||
uiShow()->showBox(Box(SettingsBox, _call));
|
||||
});
|
||||
trackControls(_trackControls, true);
|
||||
}
|
||||
|
@ -915,13 +852,13 @@ void Panel::setupMembers() {
|
|||
_countdown.destroy();
|
||||
_startsWhen.destroy();
|
||||
|
||||
_members.create(widget(), _call, mode(), _window.backend());
|
||||
_members.create(widget(), _call, mode(), _window->backend());
|
||||
|
||||
setupVideo(_viewport.get());
|
||||
setupVideo(_members->viewport());
|
||||
_viewport->mouseInsideValue(
|
||||
) | rpl::filter([=] {
|
||||
return !_fullScreenOrMaximized.current();
|
||||
return !_rtmpFull;
|
||||
}) | rpl::start_with_next([=](bool inside) {
|
||||
toggleWideControls(inside);
|
||||
}, _viewport->lifetime());
|
||||
|
@ -996,7 +933,7 @@ Fn<void(Fn<void(bool)> finished)> Panel::shareConferenceLinkCallback() {
|
|||
onstack(!link.isEmpty());
|
||||
}
|
||||
};
|
||||
ExportConferenceCallLink(uiShow(), _call->conferenceCall(), {
|
||||
ExportConferenceCallLink(sessionShow(), _call->conferenceCall(), {
|
||||
.finished = done,
|
||||
.st = DarkConferenceCallLinkStyle(),
|
||||
});
|
||||
|
@ -1004,8 +941,9 @@ Fn<void(Fn<void(bool)> finished)> Panel::shareConferenceLinkCallback() {
|
|||
}
|
||||
|
||||
void Panel::migrationShowShareLink() {
|
||||
uiShow()->hideLayer(anim::type::instant);
|
||||
ShowConferenceCallLinkBox(
|
||||
uiShow(),
|
||||
sessionShow(),
|
||||
_call->conferenceCall(),
|
||||
_call->existingConferenceLink(),
|
||||
{ .st = DarkConferenceCallLinkStyle() });
|
||||
|
@ -1013,7 +951,7 @@ void Panel::migrationShowShareLink() {
|
|||
|
||||
void Panel::migrationInviteUsers(std::vector<InviteRequest> users) {
|
||||
const auto done = [=](InviteResult result) {
|
||||
showToast({ ComposeInviteResultToast(result) });
|
||||
uiShow()->showToast({ ComposeInviteResultToast(result) });
|
||||
};
|
||||
_call->inviteUsers(std::move(users), crl::guard(this, done));
|
||||
}
|
||||
|
@ -1100,7 +1038,7 @@ void Panel::raiseControls() {
|
|||
if (_pinOnTop) {
|
||||
_pinOnTop->raise();
|
||||
}
|
||||
_layerBg->raise();
|
||||
_window->raiseLayers();
|
||||
if (_niceTooltip) {
|
||||
_niceTooltip->raise();
|
||||
}
|
||||
|
@ -1178,7 +1116,7 @@ void Panel::toggleWideControls(bool shown) {
|
|||
return;
|
||||
}
|
||||
_showWideControls = shown;
|
||||
crl::on_main(widget(), [=] {
|
||||
crl::on_main(this, [=] {
|
||||
updateWideControlsVisibility();
|
||||
});
|
||||
}
|
||||
|
@ -1189,7 +1127,7 @@ void Panel::updateWideControlsVisibility() {
|
|||
if (_wideControlsShown == shown) {
|
||||
return;
|
||||
}
|
||||
_viewport->setCursorShown(!_fullScreenOrMaximized.current() || shown);
|
||||
_viewport->setCursorShown(!_rtmpFull || shown);
|
||||
_wideControlsShown = shown;
|
||||
_wideControlsAnimation.start(
|
||||
[=] { updateButtonsGeometry(); },
|
||||
|
@ -1216,7 +1154,7 @@ void Panel::subscribeToChanges(not_null<Data::GroupCall*> real) {
|
|||
const auto skip = st::groupCallRecordingMarkSkip;
|
||||
_recordingMark->resize(size + 2 * skip, size + 2 * skip);
|
||||
_recordingMark->setClickedCallback([=] {
|
||||
showToast({ (livestream
|
||||
uiShow()->showToast({ (livestream
|
||||
? tr::lng_group_call_is_recorded_channel
|
||||
: real->recordVideo()
|
||||
? tr::lng_group_call_is_recorded_video
|
||||
|
@ -1262,7 +1200,7 @@ void Panel::subscribeToChanges(not_null<Data::GroupCall*> real) {
|
|||
*startedAsVideo = isVideo;
|
||||
}
|
||||
validateRecordingMark(recorded);
|
||||
showToast((recorded
|
||||
uiShow()->showToast((recorded
|
||||
? (livestream
|
||||
? tr::lng_group_call_recording_started_channel
|
||||
: isVideo
|
||||
|
@ -1323,7 +1261,7 @@ void Panel::createPinOnTop() {
|
|||
pin ? &st::groupCallPinnedOnTop : nullptr,
|
||||
pin ? &st::groupCallPinnedOnTop : nullptr);
|
||||
if (!_pinOnTop->isHidden()) {
|
||||
showToast({ pin
|
||||
uiShow()->showToast({ pin
|
||||
? tr::lng_group_call_pinned_on_top(tr::now)
|
||||
: tr::lng_group_call_unpinned_on_top(tr::now) });
|
||||
}
|
||||
|
@ -1331,11 +1269,9 @@ void Panel::createPinOnTop() {
|
|||
};
|
||||
_fullScreenOrMaximized.value(
|
||||
) | rpl::start_with_next([=](bool fullScreenOrMaximized) {
|
||||
#ifndef Q_OS_MAC
|
||||
_controls->controls.setStyle(fullScreenOrMaximized
|
||||
_window->setControlsStyle(fullScreenOrMaximized
|
||||
? st::callTitle
|
||||
: st::groupCallTitle);
|
||||
#endif // Q_OS_MAC
|
||||
|
||||
_pinOnTop->setVisible(!fullScreenOrMaximized);
|
||||
if (fullScreenOrMaximized) {
|
||||
|
@ -1425,7 +1361,7 @@ void Panel::refreshTopButton() {
|
|||
|
||||
void Panel::screenSharingPrivacyRequest() {
|
||||
if (auto box = ScreenSharingPrivacyRequestBox()) {
|
||||
showBox(std::move(box));
|
||||
uiShow()->showBox(std::move(box));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1476,7 +1412,7 @@ void Panel::chooseShareScreenSource() {
|
|||
.confirmText = tr::lng_continue(),
|
||||
});
|
||||
*shared = box.data();
|
||||
showBox(std::move(box));
|
||||
uiShow()->showBox(std::move(box));
|
||||
}
|
||||
|
||||
void Panel::chooseJoinAs() {
|
||||
|
@ -1487,7 +1423,7 @@ void Panel::chooseJoinAs() {
|
|||
_joinAsProcess.start(
|
||||
_peer,
|
||||
context,
|
||||
std::make_shared<Show>(this),
|
||||
uiShow(),
|
||||
callback,
|
||||
_call->joinAs());
|
||||
}
|
||||
|
@ -1508,7 +1444,7 @@ void Panel::showMainMenu() {
|
|||
wide,
|
||||
[=] { chooseJoinAs(); },
|
||||
[=] { chooseShareScreenSource(); },
|
||||
[=](auto box) { showBox(std::move(box)); });
|
||||
[=](auto box) { uiShow()->showBox(std::move(box)); });
|
||||
if (_menu->empty()) {
|
||||
_wideMenuShown = false;
|
||||
_menu.destroy();
|
||||
|
@ -1574,21 +1510,21 @@ void Panel::addMembers() {
|
|||
const auto conferenceLimit = appConfig.confcallSizeLimit();
|
||||
if (_call->conference()
|
||||
&& _call->conferenceCall()->fullCount() >= conferenceLimit) {
|
||||
showToast({ tr::lng_group_call_invite_limit(tr::now) });
|
||||
uiShow()->showToast({ tr::lng_group_call_invite_limit(tr::now) });
|
||||
}
|
||||
const auto showToastCallback = [=](TextWithEntities &&text) {
|
||||
showToast(std::move(text));
|
||||
uiShow()->showToast(std::move(text));
|
||||
};
|
||||
const auto link = _call->conference()
|
||||
? shareConferenceLinkCallback()
|
||||
: nullptr;
|
||||
if (auto box = PrepareInviteBox(_call, showToastCallback, link)) {
|
||||
showBox(std::move(box));
|
||||
uiShow()->showBox(std::move(box));
|
||||
}
|
||||
}
|
||||
|
||||
void Panel::kickParticipant(not_null<PeerData*> participantPeer) {
|
||||
showBox(Box([=](not_null<Ui::GenericBox*> box) {
|
||||
uiShow()->showBox(Box([=](not_null<Ui::GenericBox*> box) {
|
||||
box->addRow(
|
||||
object_ptr<Ui::FlatLabel>(
|
||||
box.get(),
|
||||
|
@ -1621,46 +1557,6 @@ void Panel::kickParticipant(not_null<PeerData*> participantPeer) {
|
|||
}));
|
||||
}
|
||||
|
||||
void Panel::showBox(object_ptr<Ui::BoxContent> box) {
|
||||
showBox(std::move(box), Ui::LayerOption::KeepOther, anim::type::normal);
|
||||
}
|
||||
|
||||
void Panel::showBox(
|
||||
object_ptr<Ui::BoxContent> box,
|
||||
Ui::LayerOptions options,
|
||||
anim::type animated) {
|
||||
hideStickedTooltip(StickedTooltipHide::Unavailable);
|
||||
if (window()->width() < st::groupCallWidth
|
||||
|| window()->height() < st::groupCallWidth) {
|
||||
window()->resize(
|
||||
std::max(window()->width(), st::groupCallWidth),
|
||||
std::max(window()->height(), st::groupCallWidth));
|
||||
}
|
||||
_layerBg->showBox(std::move(box), options, animated);
|
||||
}
|
||||
|
||||
void Panel::showLayer(
|
||||
std::unique_ptr<Ui::LayerWidget> layer,
|
||||
Ui::LayerOptions options,
|
||||
anim::type animated) {
|
||||
hideStickedTooltip(StickedTooltipHide::Unavailable);
|
||||
if (window()->width() < st::groupCallWidth
|
||||
|| window()->height() < st::groupCallWidth) {
|
||||
window()->resize(
|
||||
std::max(window()->width(), st::groupCallWidth),
|
||||
std::max(window()->height(), st::groupCallWidth));
|
||||
}
|
||||
_layerBg->showLayer(std::move(layer), options, animated);
|
||||
}
|
||||
|
||||
void Panel::hideLayer(anim::type animated) {
|
||||
_layerBg->hideAll(animated);
|
||||
}
|
||||
|
||||
bool Panel::isLayerShown() const {
|
||||
return _layerBg->topShownLayer() != nullptr;
|
||||
}
|
||||
|
||||
void Panel::kickParticipantSure(not_null<PeerData*> participantPeer) {
|
||||
if (_call->conference()) {
|
||||
if (const auto user = participantPeer->asUser()) {
|
||||
|
@ -1689,17 +1585,16 @@ void Panel::kickParticipantSure(not_null<PeerData*> participantPeer) {
|
|||
void Panel::initLayout(ConferencePanelMigration info) {
|
||||
initGeometry(info);
|
||||
|
||||
#ifndef Q_OS_MAC
|
||||
_controls->wrap.raise();
|
||||
_window->raiseControls();
|
||||
|
||||
_controls->controls.layout().changes(
|
||||
_window->controlsLayoutChanges(
|
||||
) | rpl::start_with_next([=] {
|
||||
// _menuToggle geometry depends on _controls arrangement.
|
||||
crl::on_main(widget(), [=] { updateControlsGeometry(); });
|
||||
crl::on_main(this, [=] { updateControlsGeometry(); });
|
||||
}, lifetime());
|
||||
|
||||
raiseControls();
|
||||
#endif // !Q_OS_MAC
|
||||
updateControlsGeometry();
|
||||
}
|
||||
|
||||
void Panel::showControls() {
|
||||
|
@ -1714,7 +1609,7 @@ void Panel::closeBeforeDestroy() {
|
|||
}
|
||||
|
||||
rpl::lifetime &Panel::lifetime() {
|
||||
return window()->lifetime();
|
||||
return _lifetime;
|
||||
}
|
||||
|
||||
void Panel::initGeometry(ConferencePanelMigration info) {
|
||||
|
@ -1724,15 +1619,7 @@ void Panel::initGeometry(ConferencePanelMigration info) {
|
|||
const auto minHeight = _call->rtmp()
|
||||
? st::groupCallHeightRtmpMin
|
||||
: st::groupCallHeight;
|
||||
if (info.screen && !info.geometry.isEmpty()) {
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
window()->setScreen(info.screen);
|
||||
#else // Qt >= 6.0.0
|
||||
window()->createWinId();
|
||||
window()->windowHandle()->setScreen(info.screen);
|
||||
#endif // Qt < 6.0.0
|
||||
window()->setGeometry(info.geometry);
|
||||
} else {
|
||||
if (!info.window) {
|
||||
const auto center = Core::App().getPointForCallPanelCenter();
|
||||
const auto width = _call->rtmp()
|
||||
? st::groupCallWidthRtmp
|
||||
|
@ -1763,7 +1650,7 @@ QRect Panel::computeTitleRect() const {
|
|||
#ifdef Q_OS_MAC
|
||||
return QRect(70, 0, width - remove - 70, 28);
|
||||
#else // Q_OS_MAC
|
||||
const auto controls = _controls->controls.geometry();
|
||||
const auto controls = _window->controlsGeometry();
|
||||
const auto right = controls.x() + controls.width() + skip;
|
||||
return (controls.center().x() < width / 2)
|
||||
? QRect(right, 0, width - right - remove, controls.height())
|
||||
|
@ -1925,7 +1812,7 @@ void Panel::refreshControlsBackground() {
|
|||
}
|
||||
|
||||
void Panel::refreshTitleBackground() {
|
||||
if (!_fullScreenOrMaximized.current()) {
|
||||
if (!_rtmpFull) {
|
||||
_titleBackground.destroy();
|
||||
return;
|
||||
} else if (_titleBackground) {
|
||||
|
@ -2070,7 +1957,7 @@ void Panel::trackControl(Ui::RpWidget *widget, rpl::lifetime &lifetime) {
|
|||
}
|
||||
|
||||
void Panel::trackControlOver(not_null<Ui::RpWidget*> control, bool over) {
|
||||
if (_fullScreenOrMaximized.current()) {
|
||||
if (_rtmpFull) {
|
||||
return;
|
||||
} else if (_stickedTooltipClose) {
|
||||
if (!over) {
|
||||
|
@ -2111,7 +1998,7 @@ void Panel::showStickedTooltip() {
|
|||
&& callReady
|
||||
&& _mute
|
||||
&& !_call->mutedByAdmin()
|
||||
&& !_layerBg->topShownLayer()) {
|
||||
&& !_window->topShownLayer()) {
|
||||
if (_stickedTooltipClose) {
|
||||
// Showing already.
|
||||
return;
|
||||
|
@ -2314,10 +2201,10 @@ void Panel::updateControlsGeometry() {
|
|||
const auto controlsOnTheLeft = true;
|
||||
const auto controlsPadding = 0;
|
||||
#else // Q_OS_MAC
|
||||
const auto center = _controls->controls.geometry().center();
|
||||
const auto center = _window->controlsGeometry().center();
|
||||
const auto controlsOnTheLeft = center.x()
|
||||
< widget()->width() / 2;
|
||||
const auto controlsPadding = _controls->wrap.y();
|
||||
const auto controlsPadding = _window->controlsWrapTop();
|
||||
#endif // Q_OS_MAC
|
||||
const auto menux = st::groupCallMenuTogglePosition.x();
|
||||
const auto menuy = st::groupCallMenuTogglePosition.y();
|
||||
|
@ -2425,7 +2312,7 @@ void Panel::updateButtonsGeometry() {
|
|||
_controlsBackgroundWide->setGeometry(
|
||||
rect.marginsAdded(st::groupCallControlsBackMargin));
|
||||
}
|
||||
if (_fullScreenOrMaximized.current()) {
|
||||
if (_rtmpFull) {
|
||||
refreshTitleGeometry();
|
||||
}
|
||||
} else {
|
||||
|
@ -2493,10 +2380,9 @@ void Panel::updateMembersGeometry() {
|
|||
_members->setVisible(!_call->rtmp());
|
||||
const auto desiredHeight = _members->desiredHeight();
|
||||
if (mode() == PanelMode::Wide) {
|
||||
const auto full = _fullScreenOrMaximized.current();
|
||||
const auto skip = full ? 0 : st::groupCallNarrowSkip;
|
||||
const auto skip = _rtmpFull ? 0 : st::groupCallNarrowSkip;
|
||||
const auto membersWidth = st::groupCallNarrowMembersWidth;
|
||||
const auto top = full ? 0 : st::groupCallWideVideoTop;
|
||||
const auto top = _rtmpFull ? 0 : st::groupCallWideVideoTop;
|
||||
_members->setGeometry(
|
||||
widget()->width() - skip - membersWidth,
|
||||
top,
|
||||
|
@ -2505,7 +2391,7 @@ void Panel::updateMembersGeometry() {
|
|||
const auto viewportSkip = _call->rtmp()
|
||||
? 0
|
||||
: (skip + membersWidth);
|
||||
_viewport->setGeometry(full, {
|
||||
_viewport->setGeometry(_rtmpFull, {
|
||||
skip,
|
||||
top,
|
||||
widget()->width() - viewportSkip - 2 * skip,
|
||||
|
@ -2654,9 +2540,8 @@ void Panel::refreshTitleGeometry() {
|
|||
? st::groupCallTitleTop
|
||||
: (st::groupCallWideVideoTop
|
||||
- st::groupCallTitleLabel.style.font->height) / 2;
|
||||
const auto shown = _fullScreenOrMaximized.current()
|
||||
? _wideControlsAnimation.value(
|
||||
_wideControlsShown ? 1. : 0.)
|
||||
const auto shown = _rtmpFull
|
||||
? _wideControlsAnimation.value(_wideControlsShown ? 1. : 0.)
|
||||
: 1.;
|
||||
const auto top = anim::interpolate(
|
||||
-_title->height() - st::boxRadius,
|
||||
|
@ -2720,10 +2605,7 @@ void Panel::refreshTitleGeometry() {
|
|||
} else {
|
||||
layout(left + titleRect.width() - best);
|
||||
}
|
||||
|
||||
#ifndef Q_OS_MAC
|
||||
_controlsTop = anim::interpolate(-_controls->wrap.height(), 0, shown);
|
||||
#endif // Q_OS_MAC
|
||||
_window->setControlsShown(shown);
|
||||
}
|
||||
|
||||
void Panel::refreshTitleColors() {
|
||||
|
@ -2760,11 +2642,11 @@ bool Panel::handleClose() {
|
|||
}
|
||||
|
||||
not_null<Ui::RpWindow*> Panel::window() const {
|
||||
return _window.window();
|
||||
return _window->window();
|
||||
}
|
||||
|
||||
not_null<Ui::RpWidget*> Panel::widget() const {
|
||||
return _window.widget();
|
||||
return _window->widget();
|
||||
}
|
||||
|
||||
} // namespace Calls::Group
|
||||
|
|
|
@ -7,32 +7,26 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
#include "base/weak_ptr.h"
|
||||
#include "base/timer.h"
|
||||
#include "base/flags.h"
|
||||
#include "base/object_ptr.h"
|
||||
#include "base/unique_qptr.h"
|
||||
#include "calls/group/calls_group_call.h"
|
||||
#include "calls/group/calls_group_common.h"
|
||||
#include "calls/group/calls_choose_join_as.h"
|
||||
#include "calls/group/ui/desktop_capture_choose_source.h"
|
||||
#include "ui/effects/animations.h"
|
||||
#include "ui/gl/gl_window.h"
|
||||
#include "ui/layers/show.h"
|
||||
#include "ui/rp_widget.h"
|
||||
|
||||
class Image;
|
||||
|
||||
namespace base {
|
||||
class PowerSaveBlocker;
|
||||
} // namespace base
|
||||
|
||||
namespace Data {
|
||||
class PhotoMedia;
|
||||
class GroupCall;
|
||||
} // namespace Data
|
||||
|
||||
namespace Main {
|
||||
class SessionShow;
|
||||
} // namespace Main
|
||||
|
||||
namespace Ui {
|
||||
class Show;
|
||||
class BoxContent;
|
||||
class LayerWidget;
|
||||
enum class LayerOption;
|
||||
|
@ -45,13 +39,13 @@ class CallMuteButton;
|
|||
class IconButton;
|
||||
class FlatLabel;
|
||||
class RpWidget;
|
||||
class RpWindow;
|
||||
template <typename Widget>
|
||||
class FadeWrap;
|
||||
template <typename Widget>
|
||||
class PaddingWrap;
|
||||
class ScrollArea;
|
||||
class GenericBox;
|
||||
class LayerManager;
|
||||
class GroupCallScheduledLeft;
|
||||
} // namespace Ui
|
||||
|
||||
|
@ -60,14 +54,6 @@ class Instance;
|
|||
struct Config;
|
||||
} // namespace Ui::Toast
|
||||
|
||||
namespace Ui::Platform {
|
||||
struct SeparateTitleControls;
|
||||
} // namespace Ui::Platform
|
||||
|
||||
namespace Main {
|
||||
class SessionShow;
|
||||
} // namespace Main
|
||||
|
||||
namespace style {
|
||||
struct CallSignalBars;
|
||||
struct CallBodyLayout;
|
||||
|
@ -76,6 +62,7 @@ struct CallBodyLayout;
|
|||
namespace Calls {
|
||||
struct InviteRequest;
|
||||
struct ConferencePanelMigration;
|
||||
class Window;
|
||||
} // namespace Calls
|
||||
|
||||
namespace Calls::Group {
|
||||
|
@ -100,37 +87,20 @@ public:
|
|||
[[nodiscard]] bool isVisible() const;
|
||||
[[nodiscard]] bool isActive() const;
|
||||
|
||||
base::weak_ptr<Ui::Toast::Instance> showToast(
|
||||
const QString &text,
|
||||
crl::time duration = 0);
|
||||
base::weak_ptr<Ui::Toast::Instance> showToast(
|
||||
TextWithEntities &&text,
|
||||
crl::time duration = 0);
|
||||
base::weak_ptr<Ui::Toast::Instance> showToast(
|
||||
Ui::Toast::Config &&config);
|
||||
|
||||
void showBox(object_ptr<Ui::BoxContent> box);
|
||||
void showBox(
|
||||
object_ptr<Ui::BoxContent> box,
|
||||
Ui::LayerOptions options,
|
||||
anim::type animated = anim::type::normal);
|
||||
void showLayer(
|
||||
std::unique_ptr<Ui::LayerWidget> layer,
|
||||
Ui::LayerOptions options,
|
||||
anim::type animated = anim::type::normal);
|
||||
void hideLayer(anim::type animated = anim::type::normal);
|
||||
[[nodiscard]] bool isLayerShown() const;
|
||||
|
||||
void migrationShowShareLink();
|
||||
void migrationInviteUsers(std::vector<InviteRequest> users);
|
||||
|
||||
void minimize();
|
||||
void toggleFullScreen();
|
||||
void toggleFullScreen(bool fullscreen);
|
||||
void close();
|
||||
void showAndActivate();
|
||||
void closeBeforeDestroy();
|
||||
|
||||
[[nodiscard]] std::shared_ptr<Main::SessionShow> uiShow();
|
||||
[[nodiscard]] std::shared_ptr<Main::SessionShow> sessionShow();
|
||||
[[nodiscard]] std::shared_ptr<Ui::Show> uiShow();
|
||||
|
||||
[[nodiscard]] not_null<Ui::RpWindow*> window() const;
|
||||
|
||||
rpl::lifetime &lifetime();
|
||||
|
||||
|
@ -148,8 +118,6 @@ private:
|
|||
Discarded,
|
||||
};
|
||||
|
||||
[[nodiscard]] not_null<Ui::RpWindow*> window() const;
|
||||
|
||||
[[nodiscard]] PanelMode mode() const;
|
||||
|
||||
void paint(QRect clip);
|
||||
|
@ -237,18 +205,11 @@ private:
|
|||
const not_null<GroupCall*> _call;
|
||||
not_null<PeerData*> _peer;
|
||||
|
||||
Ui::GL::Window _window;
|
||||
const std::unique_ptr<Ui::LayerManager> _layerBg;
|
||||
std::shared_ptr<Window> _window;
|
||||
rpl::variable<PanelMode> _mode;
|
||||
rpl::variable<bool> _fullScreenOrMaximized = false;
|
||||
bool _unpinnedMaximized = false;
|
||||
|
||||
#ifndef Q_OS_MAC
|
||||
rpl::variable<int> _controlsTop = 0;
|
||||
const std::unique_ptr<Ui::Platform::SeparateTitleControls> _controls;
|
||||
#endif // !Q_OS_MAC
|
||||
|
||||
const std::unique_ptr<base::PowerSaveBlocker> _powerSaveBlocker;
|
||||
bool _rtmpFull = false;
|
||||
|
||||
rpl::lifetime _callLifetime;
|
||||
|
||||
|
@ -305,6 +266,7 @@ private:
|
|||
rpl::lifetime _hideControlsTimerLifetime;
|
||||
|
||||
rpl::lifetime _peerLifetime;
|
||||
rpl::lifetime _lifetime;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "calls/group/calls_group_panel.h"
|
||||
#include "data/data_peer.h"
|
||||
#include "data/data_group_call.h"
|
||||
#include "ui/layers/show.h"
|
||||
#include "ui/text/text_utilities.h"
|
||||
#include "ui/toast/toast.h"
|
||||
#include "lang/lang_keys.h"
|
||||
|
@ -49,7 +50,7 @@ void Toasts::setupJoinAsChanged() {
|
|||
return (state == State::Joined);
|
||||
}) | rpl::take(1);
|
||||
}) | rpl::flatten_latest() | rpl::start_with_next([=] {
|
||||
_panel->showToast((_call->peer()->isBroadcast()
|
||||
_panel->uiShow()->showToast((_call->peer()->isBroadcast()
|
||||
? tr::lng_group_call_join_as_changed_channel
|
||||
: tr::lng_group_call_join_as_changed)(
|
||||
tr::now,
|
||||
|
@ -69,7 +70,7 @@ void Toasts::setupTitleChanged() {
|
|||
? peer->name()
|
||||
: peer->groupCall()->title();
|
||||
}) | rpl::start_with_next([=](const QString &title) {
|
||||
_panel->showToast((_call->peer()->isBroadcast()
|
||||
_panel->uiShow()->showToast((_call->peer()->isBroadcast()
|
||||
? tr::lng_group_call_title_changed_channel
|
||||
: tr::lng_group_call_title_changed)(
|
||||
tr::now,
|
||||
|
@ -83,7 +84,8 @@ void Toasts::setupAllowedToSpeak() {
|
|||
_call->allowedToSpeakNotifications(
|
||||
) | rpl::start_with_next([=] {
|
||||
if (_panel->isActive()) {
|
||||
_panel->showToast(tr::lng_group_call_can_speak_here(tr::now));
|
||||
_panel->uiShow()->showToast(
|
||||
tr::lng_group_call_can_speak_here(tr::now));
|
||||
} else {
|
||||
const auto real = _call->lookupReal();
|
||||
const auto name = (real && !real->title().isEmpty())
|
||||
|
@ -137,7 +139,7 @@ void Toasts::setupPinnedVideo() {
|
|||
: tr::lng_group_call_unpinned_screen);
|
||||
return key(tr::now, lt_user, peer->shortName());
|
||||
}();
|
||||
_panel->showToast(text);
|
||||
_panel->uiShow()->showToast(text);
|
||||
}, _lifetime);
|
||||
}
|
||||
|
||||
|
@ -146,7 +148,7 @@ void Toasts::setupRequestedToSpeak() {
|
|||
) | rpl::combine_previous(
|
||||
) | rpl::start_with_next([=](MuteState was, MuteState now) {
|
||||
if (was == MuteState::ForceMuted && now == MuteState::RaisedHand) {
|
||||
_panel->showToast(
|
||||
_panel->uiShow()->showToast(
|
||||
tr::lng_group_call_tooltip_raised_hand(tr::now));
|
||||
}
|
||||
}, _lifetime);
|
||||
|
@ -173,7 +175,7 @@ void Toasts::setupError() {
|
|||
}
|
||||
Unexpected("Error in Calls::Group::Toasts::setupErrorToasts.");
|
||||
}();
|
||||
_panel->showToast({ key(tr::now) }, kErrorDuration);
|
||||
_panel->uiShow()->showToast({ key(tr::now) }, kErrorDuration);
|
||||
}, _lifetime);
|
||||
}
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 720eaf44a529da50f5277fd6874318d9a08b735a
|
||||
Subproject commit 419049fcbe88c68486609232c4db7550833c74ca
|
Loading…
Add table
Reference in a new issue