mirror of
https://github.com/kotatogram/kotatogram-desktop
synced 2025-08-31 14:45:14 +00:00
Added ability to start video recording in group calls.
This commit is contained in:
@@ -1314,3 +1314,14 @@ groupCallStickedTooltipClose: IconButton(defaultIconButton) {
|
||||
}
|
||||
groupCallNiceTooltipTop: 4px;
|
||||
groupCallPaused: icon {{ "calls/video_large_paused", groupCallVideoTextFg }};
|
||||
|
||||
groupCallRecordingSubLabel: FlatLabel(boxDividerLabel) {
|
||||
margin: margins(0px, 0px, 0px, 0px);
|
||||
textFg: groupCallMemberNotJoinedStatus;
|
||||
align: align(top);
|
||||
}
|
||||
groupCallRecordingInfoMargins: margins(0px, 22px, 0px, 22px);
|
||||
groupCallRecordingSubLabelMargins: margins(8px, 22px, 8px, 22px);
|
||||
groupCallRecordingAudioSkip: 23px;
|
||||
groupCallRecordingSelectWidth: 2px;
|
||||
groupCallRecordingInfoHeight: 204px;
|
||||
|
@@ -2184,7 +2184,11 @@ void GroupCall::changeTitle(const QString &title) {
|
||||
}).send();
|
||||
}
|
||||
|
||||
void GroupCall::toggleRecording(bool enabled, const QString &title) {
|
||||
void GroupCall::toggleRecording(
|
||||
bool enabled,
|
||||
const QString &title,
|
||||
bool video,
|
||||
bool videoPortrait) {
|
||||
const auto real = lookupReal();
|
||||
if (!real) {
|
||||
return;
|
||||
@@ -2201,10 +2205,11 @@ void GroupCall::toggleRecording(bool enabled, const QString &title) {
|
||||
using Flag = MTPphone_ToggleGroupCallRecord::Flag;
|
||||
_api.request(MTPphone_ToggleGroupCallRecord(
|
||||
MTP_flags((enabled ? Flag::f_start : Flag(0))
|
||||
| (video ? Flag::f_video : Flag(0))
|
||||
| (title.isEmpty() ? Flag(0) : Flag::f_title)),
|
||||
inputCall(),
|
||||
MTP_string(title),
|
||||
MTPBool() // video_portrait
|
||||
MTP_bool(videoPortrait)
|
||||
)).done([=](const MTPUpdates &result) {
|
||||
_peer->session().api().applyUpdates(result);
|
||||
_recordingStoppedByMe = false;
|
||||
|
@@ -245,7 +245,11 @@ public:
|
||||
void handlePossibleCreateOrJoinResponse(
|
||||
const MTPDupdateGroupCallConnection &data);
|
||||
void changeTitle(const QString &title);
|
||||
void toggleRecording(bool enabled, const QString &title);
|
||||
void toggleRecording(
|
||||
bool enabled,
|
||||
const QString &title,
|
||||
bool video,
|
||||
bool videoPortrait);
|
||||
[[nodiscard]] bool recordingStoppedByMe() const {
|
||||
return _recordingStoppedByMe;
|
||||
}
|
||||
|
@@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "calls/group/calls_group_call.h"
|
||||
#include "calls/group/calls_group_settings.h"
|
||||
#include "calls/group/calls_group_panel.h"
|
||||
#include "calls/group/ui/calls_group_recording_box.h"
|
||||
#include "data/data_peer.h"
|
||||
#include "data/data_group_call.h"
|
||||
#include "info/profile/info_profile_values.h" // Info::Profile::NameValue.
|
||||
@@ -31,87 +32,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
namespace Calls::Group {
|
||||
namespace {
|
||||
|
||||
constexpr auto kMaxGroupCallLength = 40;
|
||||
|
||||
void EditGroupCallTitleBox(
|
||||
not_null<Ui::GenericBox*> box,
|
||||
const QString &placeholder,
|
||||
const QString &title,
|
||||
bool livestream,
|
||||
Fn<void(QString)> done) {
|
||||
box->setTitle(livestream
|
||||
? tr::lng_group_call_edit_title_channel()
|
||||
: tr::lng_group_call_edit_title());
|
||||
const auto input = box->addRow(object_ptr<Ui::InputField>(
|
||||
box,
|
||||
st::groupCallField,
|
||||
rpl::single(placeholder),
|
||||
title));
|
||||
input->setMaxLength(kMaxGroupCallLength);
|
||||
box->setFocusCallback([=] {
|
||||
input->setFocusFast();
|
||||
});
|
||||
const auto submit = [=] {
|
||||
const auto result = input->getLastText().trimmed();
|
||||
box->closeBox();
|
||||
done(result);
|
||||
};
|
||||
QObject::connect(input, &Ui::InputField::submitted, submit);
|
||||
box->addButton(tr::lng_settings_save(), submit);
|
||||
box->addButton(tr::lng_cancel(), [=] { box->closeBox(); });
|
||||
}
|
||||
|
||||
void StartGroupCallRecordingBox(
|
||||
not_null<Ui::GenericBox*> box,
|
||||
const QString &title,
|
||||
Fn<void(QString)> done) {
|
||||
box->setTitle(tr::lng_group_call_recording_start());
|
||||
|
||||
box->addRow(
|
||||
object_ptr<Ui::FlatLabel>(
|
||||
box.get(),
|
||||
tr::lng_group_call_recording_start_sure(),
|
||||
st::groupCallBoxLabel));
|
||||
|
||||
const auto input = box->addRow(object_ptr<Ui::InputField>(
|
||||
box,
|
||||
st::groupCallField,
|
||||
tr::lng_group_call_recording_start_field(),
|
||||
title));
|
||||
box->setFocusCallback([=] {
|
||||
input->setFocusFast();
|
||||
});
|
||||
const auto submit = [=] {
|
||||
const auto result = input->getLastText().trimmed();
|
||||
box->closeBox();
|
||||
done(result);
|
||||
};
|
||||
QObject::connect(input, &Ui::InputField::submitted, submit);
|
||||
box->addButton(tr::lng_group_call_recording_start_button(), submit);
|
||||
box->addButton(tr::lng_cancel(), [=] { box->closeBox(); });
|
||||
}
|
||||
|
||||
void StopGroupCallRecordingBox(
|
||||
not_null<Ui::GenericBox*> box,
|
||||
Fn<void(QString)> done) {
|
||||
box->addRow(
|
||||
object_ptr<Ui::FlatLabel>(
|
||||
box.get(),
|
||||
tr::lng_group_call_recording_stop_sure(),
|
||||
st::groupCallBoxLabel),
|
||||
style::margins(
|
||||
st::boxRowPadding.left(),
|
||||
st::boxPadding.top(),
|
||||
st::boxRowPadding.right(),
|
||||
st::boxPadding.bottom()));
|
||||
|
||||
box->addButton(tr::lng_box_ok(), [=] {
|
||||
box->closeBox();
|
||||
done(QString());
|
||||
});
|
||||
box->addButton(tr::lng_cancel(), [=] { box->closeBox(); });
|
||||
}
|
||||
|
||||
class JoinAsAction final : public Ui::Menu::ItemBase {
|
||||
public:
|
||||
JoinAsAction(
|
||||
@@ -632,10 +552,15 @@ void FillMenu(
|
||||
if (!real) {
|
||||
return;
|
||||
}
|
||||
const auto type = std::make_shared<RecordingType>();
|
||||
const auto recordStartDate = real->recordStartDate();
|
||||
const auto done = [=](QString title) {
|
||||
if (const auto strong = weak.get()) {
|
||||
strong->toggleRecording(!recordStartDate, title);
|
||||
strong->toggleRecording(
|
||||
!recordStartDate,
|
||||
title,
|
||||
(*type) != RecordingType::AudioOnly,
|
||||
(*type) == RecordingType::VideoPortrait);
|
||||
}
|
||||
};
|
||||
if (recordStartDate) {
|
||||
@@ -643,10 +568,14 @@ void FillMenu(
|
||||
StopGroupCallRecordingBox,
|
||||
done));
|
||||
} else {
|
||||
showBox(Box(
|
||||
StartGroupCallRecordingBox,
|
||||
real->title(),
|
||||
done));
|
||||
const auto typeDone = [=](RecordingType newType) {
|
||||
*type = newType;
|
||||
showBox(Box(
|
||||
AddTitleGroupCallRecordingBox,
|
||||
real->title(),
|
||||
done));
|
||||
};
|
||||
showBox(Box(StartGroupCallRecordingBox, typeDone));
|
||||
}
|
||||
};
|
||||
menu->addAction(MakeRecordingAction(
|
||||
|
@@ -1028,19 +1028,28 @@ void Panel::subscribeToChanges(not_null<Data::GroupCall*> real) {
|
||||
};
|
||||
|
||||
using namespace rpl::mappers;
|
||||
const auto startedAsVideo = std::make_shared<bool>(real->recordVideo());
|
||||
real->recordStartDateChanges(
|
||||
) | rpl::map(
|
||||
_1 != 0
|
||||
) | rpl::distinct_until_changed(
|
||||
) | rpl::start_with_next([=](bool recorded) {
|
||||
const auto livestream = _call->peer()->isBroadcast();
|
||||
const auto isVideo = real->recordVideo();
|
||||
if (recorded) {
|
||||
*startedAsVideo = isVideo;
|
||||
}
|
||||
validateRecordingMark(recorded);
|
||||
showToast((recorded
|
||||
? (livestream
|
||||
? tr::lng_group_call_recording_started_channel
|
||||
: isVideo
|
||||
? tr::lng_group_call_recording_started_video
|
||||
: tr::lng_group_call_recording_started)
|
||||
: _call->recordingStoppedByMe()
|
||||
? tr::lng_group_call_recording_saved
|
||||
? ((*startedAsVideo)
|
||||
? tr::lng_group_call_recording_saved_video
|
||||
: tr::lng_group_call_recording_saved)
|
||||
: (livestream
|
||||
? tr::lng_group_call_recording_stopped_channel
|
||||
: tr::lng_group_call_recording_stopped))(
|
||||
|
@@ -0,0 +1,376 @@
|
||||
/*
|
||||
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/group/ui/calls_group_recording_box.h"
|
||||
|
||||
#include "lang/lang_keys.h"
|
||||
#include "ui/effects/animations.h"
|
||||
#include "ui/image/image_prepare.h"
|
||||
#include "ui/layers/generic_box.h"
|
||||
#include "ui/widgets/checkbox.h"
|
||||
#include "ui/widgets/input_fields.h"
|
||||
#include "ui/widgets/labels.h"
|
||||
#include "styles/style_calls.h"
|
||||
#include "styles/style_layers.h"
|
||||
#include "styles/style_boxes.h"
|
||||
|
||||
#include <QSvgRenderer>
|
||||
|
||||
namespace Calls::Group {
|
||||
namespace {
|
||||
|
||||
constexpr auto kRoundRadius = 9;
|
||||
constexpr auto kMaxGroupCallLength = 40;
|
||||
constexpr auto kSwitchDuration = 200;
|
||||
constexpr auto kSelectDuration = 120;
|
||||
|
||||
class GraphicButton final : public Ui::AbstractButton {
|
||||
public:
|
||||
GraphicButton(
|
||||
not_null<Ui::RpWidget*> parent,
|
||||
const QString &filename,
|
||||
int selectWidth = 0);
|
||||
|
||||
void setToggled(bool value);
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *e);
|
||||
|
||||
private:
|
||||
const style::margins _margins;
|
||||
QSvgRenderer _renderer;
|
||||
Ui::RoundRect _roundRect;
|
||||
Ui::RoundRect _roundRectSelect;
|
||||
Ui::Animations::Simple _animation;
|
||||
bool _toggled = false;
|
||||
};
|
||||
|
||||
class RecordingInfo final : public Ui::RpWidget {
|
||||
public:
|
||||
RecordingInfo(not_null<Ui::RpWidget*> parent);
|
||||
|
||||
void prepareAudio();
|
||||
void prepareVideo();
|
||||
|
||||
RecordingType type() const;
|
||||
|
||||
private:
|
||||
void setLabel(const QString &text);
|
||||
|
||||
const object_ptr<Ui::VerticalLayout> _container;
|
||||
RecordingType _type = RecordingType::AudioOnly;
|
||||
};
|
||||
|
||||
class Switcher final : public Ui::RpWidget {
|
||||
public:
|
||||
Switcher(
|
||||
not_null<Ui::RpWidget*> parent,
|
||||
rpl::producer<bool> &&toggled);
|
||||
|
||||
RecordingType type() const;
|
||||
|
||||
private:
|
||||
const object_ptr<Ui::BoxContentDivider> _background;
|
||||
const object_ptr<RecordingInfo> _audio;
|
||||
const object_ptr<RecordingInfo> _video;
|
||||
bool _toggled = false;
|
||||
|
||||
Ui::Animations::Simple _animation;
|
||||
};
|
||||
|
||||
GraphicButton::GraphicButton(
|
||||
not_null<Ui::RpWidget*> parent,
|
||||
const QString &filename,
|
||||
int selectWidth)
|
||||
: AbstractButton(parent)
|
||||
, _margins(selectWidth, selectWidth, selectWidth, selectWidth)
|
||||
, _renderer(u":/gui/recording/%1.svg"_q.arg(filename))
|
||||
, _roundRect(kRoundRadius, st::groupCallMembersBg)
|
||||
, _roundRectSelect(kRoundRadius, st::groupCallActiveFg) {
|
||||
const auto size = style::ConvertScale(_renderer.defaultSize());
|
||||
resize((QRect(QPoint(), size) + _margins).size());
|
||||
}
|
||||
|
||||
void GraphicButton::setToggled(bool value) {
|
||||
if (_toggled == value) {
|
||||
return;
|
||||
}
|
||||
_toggled = value;
|
||||
_animation.start(
|
||||
[=] { update(); },
|
||||
_toggled ? 0. : 1.,
|
||||
_toggled ? 1. : 0.,
|
||||
kSelectDuration);
|
||||
}
|
||||
|
||||
void GraphicButton::paintEvent(QPaintEvent *e) {
|
||||
Painter p(this);
|
||||
const auto progress = _animation.value(_toggled ? 1. : 0.);
|
||||
p.setOpacity(progress);
|
||||
_roundRectSelect.paint(p, rect());
|
||||
p.setOpacity(1.);
|
||||
const auto r = rect() - _margins;
|
||||
_roundRect.paint(p, r);
|
||||
_renderer.render(&p, r);
|
||||
}
|
||||
|
||||
RecordingInfo::RecordingInfo(not_null<Ui::RpWidget*> parent)
|
||||
: RpWidget(parent)
|
||||
, _container(this) {
|
||||
sizeValue(
|
||||
) | rpl::start_with_next([=](const QSize &size) {
|
||||
_container->resizeToWidth(size.width());
|
||||
}, _container->lifetime());
|
||||
}
|
||||
|
||||
void RecordingInfo::prepareAudio() {
|
||||
_type = RecordingType::AudioOnly;
|
||||
setLabel(tr::lng_group_call_recording_start_audio_subtitle(tr::now));
|
||||
|
||||
const auto wrap = _container->add(
|
||||
object_ptr<Ui::RpWidget>(_container),
|
||||
style::margins(0, st::groupCallRecordingAudioSkip, 0, 0));
|
||||
const auto audioIcon = Ui::CreateChild<GraphicButton>(
|
||||
wrap,
|
||||
"info_audio");
|
||||
wrap->resize(width(), audioIcon->height());
|
||||
audioIcon->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||
|
||||
sizeValue(
|
||||
) | rpl::start_with_next([=](const QSize &size) {
|
||||
audioIcon->moveToLeft((size.width() - audioIcon->width()) / 2, 0);
|
||||
}, lifetime());
|
||||
}
|
||||
|
||||
void RecordingInfo::prepareVideo() {
|
||||
setLabel(tr::lng_group_call_recording_start_video_subtitle(tr::now));
|
||||
|
||||
const auto wrap = _container->add(
|
||||
object_ptr<Ui::RpWidget>(_container),
|
||||
style::margins());
|
||||
|
||||
const auto landscapeIcon = Ui::CreateChild<GraphicButton>(
|
||||
wrap,
|
||||
"info_video_landscape",
|
||||
st::groupCallRecordingSelectWidth);
|
||||
const auto portraitIcon = Ui::CreateChild<GraphicButton>(
|
||||
wrap,
|
||||
"info_video_portrait",
|
||||
st::groupCallRecordingSelectWidth);
|
||||
wrap->resize(width(), portraitIcon->height());
|
||||
|
||||
landscapeIcon->setToggled(true);
|
||||
_type = RecordingType::VideoLandscape;
|
||||
|
||||
const auto icons = std::vector<GraphicButton*>{
|
||||
landscapeIcon,
|
||||
portraitIcon,
|
||||
};
|
||||
const auto types = std::map<GraphicButton*, RecordingType>{
|
||||
{ landscapeIcon, RecordingType::VideoLandscape },
|
||||
{ portraitIcon, RecordingType::VideoPortrait },
|
||||
};
|
||||
for (const auto icon : icons) {
|
||||
icon->clicks(
|
||||
) | rpl::start_with_next([=] {
|
||||
for (const auto &i : icons) {
|
||||
i->setToggled(icon == i);
|
||||
}
|
||||
_type = types.at(icon);
|
||||
}, lifetime());
|
||||
}
|
||||
|
||||
wrap->sizeValue(
|
||||
) | rpl::start_with_next([=](const QSize &size) {
|
||||
const auto wHalf = size.width() / icons.size();
|
||||
for (auto i = 0; i < icons.size(); i++) {
|
||||
const auto &icon = icons[i];
|
||||
icon->moveToLeft(
|
||||
wHalf * i + (wHalf - icon->width()) / 2,
|
||||
(size.height() - icon->height()) / 2);
|
||||
}
|
||||
}, lifetime());
|
||||
}
|
||||
|
||||
void RecordingInfo::setLabel(const QString &text) {
|
||||
const auto label = _container->add(
|
||||
object_ptr<Ui::FlatLabel>(
|
||||
_container,
|
||||
text,
|
||||
st::groupCallRecordingSubLabel),
|
||||
st::groupCallRecordingSubLabelMargins);
|
||||
|
||||
rpl::combine(
|
||||
sizeValue(),
|
||||
label->sizeValue()
|
||||
) | rpl::start_with_next([=](QSize my, QSize labelSize) {
|
||||
label->moveToLeft(
|
||||
(my.width() - labelSize.width()) / 2,
|
||||
label->y(),
|
||||
my.width());
|
||||
}, label->lifetime());
|
||||
}
|
||||
|
||||
RecordingType RecordingInfo::type() const {
|
||||
return _type;
|
||||
}
|
||||
|
||||
Switcher::Switcher(
|
||||
not_null<Ui::RpWidget*> parent,
|
||||
rpl::producer<bool> &&toggled)
|
||||
: RpWidget(parent)
|
||||
, _background(this, st::groupCallRecordingInfoHeight, st::groupCallBg)
|
||||
, _audio(this)
|
||||
, _video(this) {
|
||||
_audio->prepareAudio();
|
||||
_video->prepareVideo();
|
||||
|
||||
resize(0, st::groupCallRecordingInfoHeight);
|
||||
|
||||
const auto updatePositions = [=](float64 progress) {
|
||||
_audio->moveToLeft(-width() * progress, 0);
|
||||
_video->moveToLeft(_audio->x() + _audio->width(), 0);
|
||||
};
|
||||
|
||||
sizeValue(
|
||||
) | rpl::start_with_next([=](const QSize &size) {
|
||||
_audio->resize(size.width(), size.height());
|
||||
_video->resize(size.width(), size.height());
|
||||
|
||||
updatePositions(_toggled ? 1. : 0.);
|
||||
|
||||
_background->lower();
|
||||
_background->setGeometry(QRect(QPoint(), size));
|
||||
}, lifetime());
|
||||
|
||||
std::move(
|
||||
toggled
|
||||
) | rpl::start_with_next([=](bool toggled) {
|
||||
_toggled = toggled;
|
||||
_animation.start(
|
||||
updatePositions,
|
||||
toggled ? 0. : 1.,
|
||||
toggled ? 1. : 0.,
|
||||
kSwitchDuration);
|
||||
}, lifetime());
|
||||
}
|
||||
|
||||
RecordingType Switcher::type() const {
|
||||
return _toggled ? _video->type() : _audio->type();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void EditGroupCallTitleBox(
|
||||
not_null<Ui::GenericBox*> box,
|
||||
const QString &placeholder,
|
||||
const QString &title,
|
||||
bool livestream,
|
||||
Fn<void(QString)> done) {
|
||||
box->setTitle(livestream
|
||||
? tr::lng_group_call_edit_title_channel()
|
||||
: tr::lng_group_call_edit_title());
|
||||
const auto input = box->addRow(object_ptr<Ui::InputField>(
|
||||
box,
|
||||
st::groupCallField,
|
||||
rpl::single(placeholder),
|
||||
title));
|
||||
input->setMaxLength(kMaxGroupCallLength);
|
||||
box->setFocusCallback([=] {
|
||||
input->setFocusFast();
|
||||
});
|
||||
const auto submit = [=] {
|
||||
const auto result = input->getLastText().trimmed();
|
||||
box->closeBox();
|
||||
done(result);
|
||||
};
|
||||
QObject::connect(input, &Ui::InputField::submitted, submit);
|
||||
box->addButton(tr::lng_settings_save(), submit);
|
||||
box->addButton(tr::lng_cancel(), [=] { box->closeBox(); });
|
||||
}
|
||||
|
||||
void StartGroupCallRecordingBox(
|
||||
not_null<Ui::GenericBox*> box,
|
||||
Fn<void(RecordingType)> done) {
|
||||
box->setTitle(tr::lng_group_call_recording_start());
|
||||
|
||||
box->addRow(
|
||||
object_ptr<Ui::FlatLabel>(
|
||||
box.get(),
|
||||
tr::lng_group_call_recording_start_sure(),
|
||||
st::groupCallBoxLabel));
|
||||
|
||||
const auto checkbox = box->addRow(
|
||||
object_ptr<Ui::Checkbox>(
|
||||
box,
|
||||
tr::lng_group_call_recording_start_checkbox(),
|
||||
false,
|
||||
st::groupCallCheckbox),
|
||||
style::margins(
|
||||
st::boxRowPadding.left(),
|
||||
st::boxRowPadding.left(),
|
||||
st::boxRowPadding.right(),
|
||||
st::boxRowPadding.bottom()));
|
||||
|
||||
const auto switcher = box->addRow(
|
||||
object_ptr<Switcher>(box, checkbox->checkedChanges()),
|
||||
st::groupCallRecordingInfoMargins);
|
||||
|
||||
box->addButton(tr::lng_continue(), [=] {
|
||||
const auto type = switcher->type();
|
||||
box->closeBox();
|
||||
done(type);
|
||||
});
|
||||
box->addButton(tr::lng_cancel(), [=] { box->closeBox(); });
|
||||
}
|
||||
|
||||
void AddTitleGroupCallRecordingBox(
|
||||
not_null<Ui::GenericBox*> box,
|
||||
const QString &title,
|
||||
Fn<void(QString)> done) {
|
||||
box->setTitle(tr::lng_group_call_recording_start_title());
|
||||
|
||||
const auto input = box->addRow(object_ptr<Ui::InputField>(
|
||||
box,
|
||||
st::groupCallField,
|
||||
tr::lng_group_call_recording_start_field(),
|
||||
title));
|
||||
box->setFocusCallback([=] {
|
||||
input->setFocusFast();
|
||||
});
|
||||
const auto submit = [=] {
|
||||
const auto result = input->getLastText().trimmed();
|
||||
box->closeBox();
|
||||
done(result);
|
||||
};
|
||||
QObject::connect(input, &Ui::InputField::submitted, submit);
|
||||
box->addButton(tr::lng_group_call_recording_start_button(), submit);
|
||||
box->addButton(tr::lng_cancel(), [=] { box->closeBox(); });
|
||||
}
|
||||
|
||||
|
||||
void StopGroupCallRecordingBox(
|
||||
not_null<Ui::GenericBox*> box,
|
||||
Fn<void(QString)> done) {
|
||||
box->addRow(
|
||||
object_ptr<Ui::FlatLabel>(
|
||||
box.get(),
|
||||
tr::lng_group_call_recording_stop_sure(),
|
||||
st::groupCallBoxLabel),
|
||||
style::margins(
|
||||
st::boxRowPadding.left(),
|
||||
st::boxPadding.top(),
|
||||
st::boxRowPadding.right(),
|
||||
st::boxPadding.bottom()));
|
||||
|
||||
box->addButton(tr::lng_box_ok(), [=] {
|
||||
box->closeBox();
|
||||
done(QString());
|
||||
});
|
||||
box->addButton(tr::lng_cancel(), [=] { box->closeBox(); });
|
||||
}
|
||||
|
||||
} // namespace Calls::Group
|
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
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
|
||||
|
||||
namespace Ui {
|
||||
class GenericBox;
|
||||
} // namespace Ui
|
||||
|
||||
namespace Calls::Group {
|
||||
|
||||
enum class RecordingType {
|
||||
AudioOnly,
|
||||
VideoLandscape,
|
||||
VideoPortrait,
|
||||
};
|
||||
|
||||
void EditGroupCallTitleBox(
|
||||
not_null<Ui::GenericBox*> box,
|
||||
const QString &placeholder,
|
||||
const QString &title,
|
||||
bool livestream,
|
||||
Fn<void(QString)> done);
|
||||
|
||||
void StartGroupCallRecordingBox(
|
||||
not_null<Ui::GenericBox*> box,
|
||||
Fn<void(RecordingType)> done);
|
||||
|
||||
void AddTitleGroupCallRecordingBox(
|
||||
not_null<Ui::GenericBox*> box,
|
||||
const QString &title,
|
||||
Fn<void(QString)> done);
|
||||
|
||||
void StopGroupCallRecordingBox(
|
||||
not_null<Ui::GenericBox*> box,
|
||||
Fn<void(QString)> done);
|
||||
|
||||
} // namespace Calls::Group
|
@@ -389,7 +389,10 @@ void GroupCall::applyCallFields(const MTPDgroupCall &data) {
|
||||
setServerParticipantsCount(data.vparticipants_count().v);
|
||||
changePeerEmptyCallFlag();
|
||||
_title = qs(data.vtitle().value_or_empty());
|
||||
_recordStartDate = data.vrecord_start_date().value_or_empty();
|
||||
{
|
||||
_recordVideo = data.is_record_video_active();
|
||||
_recordStartDate = data.vrecord_start_date().value_or_empty();
|
||||
}
|
||||
_scheduleDate = data.vschedule_date().value_or_empty();
|
||||
_scheduleStartSubscribed = data.is_schedule_start_subscribed();
|
||||
_unmutedVideoLimit = data.vunmuted_video_limit().v;
|
||||
|
@@ -98,6 +98,9 @@ public:
|
||||
[[nodiscard]] int unmutedVideoLimit() const {
|
||||
return _unmutedVideoLimit.current();
|
||||
}
|
||||
[[nodiscard]] bool recordVideo() const {
|
||||
return _recordVideo.current();
|
||||
}
|
||||
|
||||
void setPeer(not_null<PeerData*> peer);
|
||||
|
||||
@@ -214,6 +217,7 @@ private:
|
||||
int _serverParticipantsCount = 0;
|
||||
rpl::variable<int> _fullCount = 0;
|
||||
rpl::variable<int> _unmutedVideoLimit = 0;
|
||||
rpl::variable<bool> _recordVideo = 0;
|
||||
rpl::variable<TimeId> _recordStartDate = 0;
|
||||
rpl::variable<TimeId> _scheduleDate = 0;
|
||||
rpl::variable<bool> _scheduleStartSubscribed = false;
|
||||
|
Reference in New Issue
Block a user