mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Added RTMP info to settings of group call.
This commit is contained in:
parent
436622ad7c
commit
1f18c9a273
5 changed files with 238 additions and 128 deletions
|
@ -12,6 +12,7 @@ using "ui/layers/layers.style";
|
||||||
using "ui/chat/chat.style"; // GroupCallUserpics
|
using "ui/chat/chat.style"; // GroupCallUserpics
|
||||||
using "info/info.style"; // ShortInfoCover
|
using "info/info.style"; // ShortInfoCover
|
||||||
using "window/window.style";
|
using "window/window.style";
|
||||||
|
using "settings/settings.style"; // settingsSubsectionTitle
|
||||||
|
|
||||||
CallSignalBars {
|
CallSignalBars {
|
||||||
width: pixels;
|
width: pixels;
|
||||||
|
@ -1380,6 +1381,17 @@ groupCallRtmpShowButton: IconButton(defaultIconButton) {
|
||||||
color: windowBgOver;
|
color: windowBgOver;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
groupCallSettingsRtmpShowButton: IconButton(groupCallRtmpShowButton) {
|
||||||
|
ripple: groupCallRipple;
|
||||||
|
}
|
||||||
|
groupCallSubsectionTitle: FlatLabel(settingsSubsectionTitle) {
|
||||||
|
textFg: groupCallActiveFg;
|
||||||
|
}
|
||||||
|
groupCallAttentionBoxButton: RoundButton(groupCallBoxButton) {
|
||||||
|
textFg: attentionButtonFg;
|
||||||
|
textFgOver: attentionButtonFgOver;
|
||||||
|
}
|
||||||
|
|
||||||
groupCallRtmpUrlSkip: 1px;
|
groupCallRtmpUrlSkip: 1px;
|
||||||
groupCallRtmpKeySubsectionTitleSkip: 8px;
|
groupCallRtmpKeySubsectionTitleSkip: 8px;
|
||||||
groupCallRtmpSubsectionTitleAddPadding: margins(0px, -1px, 0px, -4px);
|
groupCallRtmpSubsectionTitleAddPadding: margins(0px, -1px, 0px, -4px);
|
||||||
|
|
|
@ -1028,6 +1028,14 @@ rpl::producer<bool> GroupCall::emptyRtmpValue() const {
|
||||||
return _emptyRtmp.value();
|
return _emptyRtmp.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString GroupCall::rtmpUrl() const {
|
||||||
|
return _rtmpUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString GroupCall::rtmpKey() const {
|
||||||
|
return _rtmpKey;
|
||||||
|
}
|
||||||
|
|
||||||
Data::GroupCall *GroupCall::lookupReal() const {
|
Data::GroupCall *GroupCall::lookupReal() const {
|
||||||
const auto real = _peer->groupCall();
|
const auto real = _peer->groupCall();
|
||||||
return (real && real->id() == _id) ? real : nullptr;
|
return (real && real->id() == _id) ? real : nullptr;
|
||||||
|
|
|
@ -19,11 +19,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/text/text_utilities.h"
|
#include "ui/text/text_utilities.h"
|
||||||
#include "ui/widgets/buttons.h"
|
#include "ui/widgets/buttons.h"
|
||||||
#include "ui/widgets/popup_menu.h"
|
#include "ui/widgets/popup_menu.h"
|
||||||
|
#include "ui/wrap/vertical_layout.h"
|
||||||
#include "styles/style_boxes.h"
|
#include "styles/style_boxes.h"
|
||||||
#include "styles/style_calls.h"
|
#include "styles/style_calls.h"
|
||||||
#include "styles/style_info.h"
|
#include "styles/style_info.h"
|
||||||
#include "styles/style_layers.h"
|
#include "styles/style_layers.h"
|
||||||
#include "styles/style_menu_icons.h"
|
#include "styles/style_menu_icons.h"
|
||||||
|
#include "styles/style_settings.h"
|
||||||
|
|
||||||
#include <QGuiApplication>
|
#include <QGuiApplication>
|
||||||
#include <QStyle>
|
#include <QStyle>
|
||||||
|
@ -41,141 +43,23 @@ void StartWithBox(
|
||||||
Fn<void(QString)> showToast,
|
Fn<void(QString)> showToast,
|
||||||
rpl::producer<StartRtmpProcess::Data> &&data) {
|
rpl::producer<StartRtmpProcess::Data> &&data) {
|
||||||
struct State {
|
struct State {
|
||||||
rpl::variable<bool> hidden = true;
|
|
||||||
rpl::variable<QString> key;
|
|
||||||
rpl::variable<QString> url;
|
|
||||||
base::unique_qptr<Ui::PopupMenu> menu;
|
base::unique_qptr<Ui::PopupMenu> menu;
|
||||||
bool warned = false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto &rowPadding = st::boxRowPadding;
|
|
||||||
|
|
||||||
const auto passChar = QChar(box->style()->styleHint(
|
|
||||||
QStyle::SH_LineEdit_PasswordCharacter));
|
|
||||||
const auto state = box->lifetime().make_state<State>();
|
const auto state = box->lifetime().make_state<State>();
|
||||||
state->key = rpl::duplicate(
|
|
||||||
data
|
|
||||||
) | rpl::map([=](const auto &d) { return d.key; });
|
|
||||||
state->url = std::move(
|
|
||||||
data
|
|
||||||
) | rpl::map([=](const auto &d) { return d.url; });
|
|
||||||
|
|
||||||
const auto addButton = [&](
|
StartRtmpProcess::FillRtmpRows(
|
||||||
bool key,
|
box->verticalLayout(),
|
||||||
rpl::producer<QString> &&text) {
|
true,
|
||||||
const auto &padding = st::groupCallRtmpCopyButton.padding;
|
std::move(showBox),
|
||||||
|
std::move(showToast),
|
||||||
auto wrap = object_ptr<Ui::RpWidget>(box);
|
std::move(data),
|
||||||
auto button = Ui::CreateChild<Ui::RoundButton>(
|
&st::boxLabel,
|
||||||
wrap.data(),
|
&st::groupCallRtmpShowButton,
|
||||||
rpl::duplicate(text),
|
&st::settingsSubsectionTitle,
|
||||||
st::groupCallRtmpCopyButton);
|
&st::attentionBoxButton);
|
||||||
button->setTextTransform(Ui::RoundButton::TextTransform::NoTransform);
|
|
||||||
button->setClickedCallback(key
|
|
||||||
? Fn<void()>([=] {
|
|
||||||
QGuiApplication::clipboard()->setText(state->key.current());
|
|
||||||
showToast(tr::lng_group_call_rtmp_key_copied(tr::now));
|
|
||||||
})
|
|
||||||
: Fn<void()>([=] {
|
|
||||||
QGuiApplication::clipboard()->setText(state->url.current());
|
|
||||||
showToast(tr::lng_group_call_rtmp_url_copied(tr::now));
|
|
||||||
}));
|
|
||||||
const auto weak = box->addRow(std::move(wrap), rowPadding);
|
|
||||||
button->heightValue(
|
|
||||||
) | rpl::start_with_next([=](int height) {
|
|
||||||
weak->resize(weak->width(), height);
|
|
||||||
}, box->lifetime());
|
|
||||||
return weak;
|
|
||||||
};
|
|
||||||
|
|
||||||
const auto addLabel = [&](
|
|
||||||
rpl::producer<QString> &&text,
|
|
||||||
const style::FlatLabel &st) {
|
|
||||||
const auto label = box->addRow(
|
|
||||||
object_ptr<Ui::FlatLabel>(box, std::move(text), st),
|
|
||||||
st::boxRowPadding);
|
|
||||||
label->setSelectable(true);
|
|
||||||
label->setBreakEverywhere(true);
|
|
||||||
return label;
|
|
||||||
};
|
|
||||||
|
|
||||||
box->setTitle(tr::lng_group_call_rtmp_title());
|
box->setTitle(tr::lng_group_call_rtmp_title());
|
||||||
|
|
||||||
// Server URL.
|
|
||||||
Settings::AddSubsectionTitle(
|
|
||||||
box->verticalLayout(),
|
|
||||||
tr::lng_group_call_rtmp_url_subtitle(),
|
|
||||||
st::groupCallRtmpSubsectionTitleAddPadding);
|
|
||||||
auto urlLabelContent = state->url.value();
|
|
||||||
addLabel(std::move(urlLabelContent), st::boxLabel);
|
|
||||||
box->addSkip(st::groupCallRtmpUrlSkip);
|
|
||||||
addButton(false, tr::lng_group_call_rtmp_url_copy());
|
|
||||||
//
|
|
||||||
|
|
||||||
Settings::AddDivider(box->verticalLayout());
|
|
||||||
|
|
||||||
// Stream Key.
|
|
||||||
box->addSkip(st::groupCallRtmpKeySubsectionTitleSkip);
|
|
||||||
Settings::AddSubsectionTitle(
|
|
||||||
box->verticalLayout(),
|
|
||||||
tr::lng_group_call_rtmp_key_subtitle(),
|
|
||||||
st::groupCallRtmpSubsectionTitleAddPadding);
|
|
||||||
|
|
||||||
auto keyLabelContent = rpl::combine(
|
|
||||||
state->hidden.value(),
|
|
||||||
state->key.value()
|
|
||||||
) | rpl::map([passChar](bool hidden, const QString &key) {
|
|
||||||
return key.isEmpty()
|
|
||||||
? QString()
|
|
||||||
: hidden
|
|
||||||
? QString().fill(passChar, kPasswordCharAmount)
|
|
||||||
: key;
|
|
||||||
});
|
|
||||||
const auto streamKeyLabel = addLabel(
|
|
||||||
std::move(keyLabelContent),
|
|
||||||
st::boxLabel);
|
|
||||||
streamKeyLabel->setSelectable(false);
|
|
||||||
const auto streamKeyButton = Ui::CreateChild<Ui::IconButton>(
|
|
||||||
box.get(),
|
|
||||||
st::groupCallRtmpShowButton);
|
|
||||||
|
|
||||||
streamKeyLabel->topValue(
|
|
||||||
) | rpl::start_with_next([=, right = rowPadding.right()](int top) {
|
|
||||||
streamKeyButton->moveToRight(
|
|
||||||
st::groupCallRtmpShowButtonPosition.x(),
|
|
||||||
top + st::groupCallRtmpShowButtonPosition.y());
|
|
||||||
streamKeyButton->raise();
|
|
||||||
}, box->lifetime());
|
|
||||||
streamKeyButton->addClickHandler([=] {
|
|
||||||
const auto toggle = [=] {
|
|
||||||
const auto newValue = !state->hidden.current();
|
|
||||||
state->hidden = newValue;
|
|
||||||
streamKeyLabel->setSelectable(!newValue);
|
|
||||||
streamKeyLabel->setAttribute(
|
|
||||||
Qt::WA_TransparentForMouseEvents,
|
|
||||||
newValue);
|
|
||||||
};
|
|
||||||
if (!state->warned && state->hidden.current()) {
|
|
||||||
showBox(Ui::MakeConfirmBox({
|
|
||||||
.text = tr::lng_group_call_rtmp_key_warning(
|
|
||||||
Ui::Text::RichLangValue),
|
|
||||||
.confirmed = [=](Fn<void()> &&close) {
|
|
||||||
state->warned = true;
|
|
||||||
toggle();
|
|
||||||
close();
|
|
||||||
},
|
|
||||||
.confirmText = tr::lng_from_request_understand(),
|
|
||||||
.cancelText = tr::lng_close(),
|
|
||||||
.confirmStyle = &st::attentionBoxButton,
|
|
||||||
}));
|
|
||||||
} else {
|
|
||||||
toggle();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
addButton(true, tr::lng_group_call_rtmp_key_copy());
|
|
||||||
//
|
|
||||||
|
|
||||||
Settings::AddDividerText(
|
Settings::AddDividerText(
|
||||||
box->verticalLayout(),
|
box->verticalLayout(),
|
||||||
tr::lng_group_call_rtmp_info());
|
tr::lng_group_call_rtmp_info());
|
||||||
|
@ -312,4 +196,169 @@ void StartRtmpProcess::createBox() {
|
||||||
_request->showBox(std::move(object));
|
_request->showBox(std::move(object));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StartRtmpProcess::FillRtmpRows(
|
||||||
|
not_null<Ui::VerticalLayout*> container,
|
||||||
|
bool divider,
|
||||||
|
Fn<void(object_ptr<Ui::BoxContent>)> showBox,
|
||||||
|
Fn<void(QString)> showToast,
|
||||||
|
rpl::producer<StartRtmpProcess::Data> &&data,
|
||||||
|
const style::FlatLabel *labelStyle,
|
||||||
|
const style::IconButton *showButtonStyle,
|
||||||
|
const style::FlatLabel *subsectionTitleStyle,
|
||||||
|
const style::RoundButton *attentionButtonStyle) {
|
||||||
|
struct State {
|
||||||
|
rpl::variable<bool> hidden = true;
|
||||||
|
rpl::variable<QString> key;
|
||||||
|
rpl::variable<QString> url;
|
||||||
|
bool warned = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto &rowPadding = st::boxRowPadding;
|
||||||
|
|
||||||
|
const auto passChar = QChar(container->style()->styleHint(
|
||||||
|
QStyle::SH_LineEdit_PasswordCharacter));
|
||||||
|
const auto state = container->lifetime().make_state<State>();
|
||||||
|
state->key = rpl::duplicate(
|
||||||
|
data
|
||||||
|
) | rpl::map([=](const auto &d) { return d.key; });
|
||||||
|
state->url = std::move(
|
||||||
|
data
|
||||||
|
) | rpl::map([=](const auto &d) { return d.url; });
|
||||||
|
|
||||||
|
const auto addButton = [&](
|
||||||
|
bool key,
|
||||||
|
rpl::producer<QString> &&text) {
|
||||||
|
const auto &padding = st::groupCallRtmpCopyButton.padding;
|
||||||
|
|
||||||
|
auto wrap = object_ptr<Ui::RpWidget>(container);
|
||||||
|
auto button = Ui::CreateChild<Ui::RoundButton>(
|
||||||
|
wrap.data(),
|
||||||
|
rpl::duplicate(text),
|
||||||
|
st::groupCallRtmpCopyButton);
|
||||||
|
button->setTextTransform(Ui::RoundButton::TextTransform::NoTransform);
|
||||||
|
button->setClickedCallback(key
|
||||||
|
? Fn<void()>([=] {
|
||||||
|
QGuiApplication::clipboard()->setText(state->key.current());
|
||||||
|
showToast(tr::lng_group_call_rtmp_key_copied(tr::now));
|
||||||
|
})
|
||||||
|
: Fn<void()>([=] {
|
||||||
|
QGuiApplication::clipboard()->setText(state->url.current());
|
||||||
|
showToast(tr::lng_group_call_rtmp_url_copied(tr::now));
|
||||||
|
}));
|
||||||
|
const auto weak = container->add(std::move(wrap), rowPadding);
|
||||||
|
button->heightValue(
|
||||||
|
) | rpl::start_with_next([=](int height) {
|
||||||
|
weak->resize(weak->width(), height);
|
||||||
|
}, container->lifetime());
|
||||||
|
return weak;
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto addLabel = [&](
|
||||||
|
rpl::producer<QString> &&text,
|
||||||
|
const style::FlatLabel &st) {
|
||||||
|
const auto label = container->add(
|
||||||
|
object_ptr<Ui::FlatLabel>(container, std::move(text), st),
|
||||||
|
st::boxRowPadding);
|
||||||
|
label->setSelectable(true);
|
||||||
|
label->setBreakEverywhere(true);
|
||||||
|
return label;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Server URL.
|
||||||
|
{
|
||||||
|
// Settings::AddSubsectionTitle
|
||||||
|
container->add(
|
||||||
|
object_ptr<Ui::FlatLabel>(
|
||||||
|
container,
|
||||||
|
tr::lng_group_call_rtmp_url_subtitle(),
|
||||||
|
*subsectionTitleStyle),
|
||||||
|
st::settingsSubsectionTitlePadding
|
||||||
|
+ st::groupCallRtmpSubsectionTitleAddPadding);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto urlLabelContent = state->url.value();
|
||||||
|
addLabel(std::move(urlLabelContent), *labelStyle);
|
||||||
|
container->add(object_ptr<Ui::FixedHeightWidget>(
|
||||||
|
container,
|
||||||
|
st::groupCallRtmpUrlSkip));
|
||||||
|
addButton(false, tr::lng_group_call_rtmp_url_copy());
|
||||||
|
//
|
||||||
|
|
||||||
|
if (divider) {
|
||||||
|
Settings::AddDivider(container);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stream Key.
|
||||||
|
container->add(object_ptr<Ui::FixedHeightWidget>(
|
||||||
|
container,
|
||||||
|
st::groupCallRtmpKeySubsectionTitleSkip));
|
||||||
|
|
||||||
|
{
|
||||||
|
// Settings::AddSubsectionTitle
|
||||||
|
container->add(
|
||||||
|
object_ptr<Ui::FlatLabel>(
|
||||||
|
container,
|
||||||
|
tr::lng_group_call_rtmp_key_subtitle(),
|
||||||
|
*subsectionTitleStyle),
|
||||||
|
st::settingsSubsectionTitlePadding
|
||||||
|
+ st::groupCallRtmpSubsectionTitleAddPadding);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto keyLabelContent = rpl::combine(
|
||||||
|
state->hidden.value(),
|
||||||
|
state->key.value()
|
||||||
|
) | rpl::map([passChar](bool hidden, const QString &key) {
|
||||||
|
return key.isEmpty()
|
||||||
|
? QString()
|
||||||
|
: hidden
|
||||||
|
? QString().fill(passChar, kPasswordCharAmount)
|
||||||
|
: key;
|
||||||
|
});
|
||||||
|
const auto streamKeyLabel = addLabel(
|
||||||
|
std::move(keyLabelContent),
|
||||||
|
*labelStyle);
|
||||||
|
streamKeyLabel->setSelectable(false);
|
||||||
|
const auto streamKeyButton = Ui::CreateChild<Ui::IconButton>(
|
||||||
|
container.get(),
|
||||||
|
*showButtonStyle);
|
||||||
|
|
||||||
|
streamKeyLabel->topValue(
|
||||||
|
) | rpl::start_with_next([=, right = rowPadding.right()](int top) {
|
||||||
|
streamKeyButton->moveToRight(
|
||||||
|
st::groupCallRtmpShowButtonPosition.x(),
|
||||||
|
top + st::groupCallRtmpShowButtonPosition.y());
|
||||||
|
streamKeyButton->raise();
|
||||||
|
}, container->lifetime());
|
||||||
|
streamKeyButton->addClickHandler([=] {
|
||||||
|
const auto toggle = [=] {
|
||||||
|
const auto newValue = !state->hidden.current();
|
||||||
|
state->hidden = newValue;
|
||||||
|
streamKeyLabel->setSelectable(!newValue);
|
||||||
|
streamKeyLabel->setAttribute(
|
||||||
|
Qt::WA_TransparentForMouseEvents,
|
||||||
|
newValue);
|
||||||
|
};
|
||||||
|
if (!state->warned && state->hidden.current()) {
|
||||||
|
showBox(Ui::MakeConfirmBox({
|
||||||
|
.text = tr::lng_group_call_rtmp_key_warning(
|
||||||
|
Ui::Text::RichLangValue),
|
||||||
|
.confirmed = [=](Fn<void()> &&close) {
|
||||||
|
state->warned = true;
|
||||||
|
toggle();
|
||||||
|
close();
|
||||||
|
},
|
||||||
|
.confirmText = tr::lng_from_request_understand(),
|
||||||
|
.cancelText = tr::lng_close(),
|
||||||
|
.confirmStyle = attentionButtonStyle,
|
||||||
|
.labelStyle = labelStyle,
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
toggle();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
addButton(true, tr::lng_group_call_rtmp_key_copy());
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Calls::Group
|
} // namespace Calls::Group
|
||||||
|
|
|
@ -14,8 +14,15 @@ class PeerData;
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class BoxContent;
|
class BoxContent;
|
||||||
|
class VerticalLayout;
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
|
||||||
|
namespace style {
|
||||||
|
struct FlatLabel;
|
||||||
|
struct RoundButton;
|
||||||
|
struct IconButton;
|
||||||
|
} // namespace style
|
||||||
|
|
||||||
namespace Calls::Group {
|
namespace Calls::Group {
|
||||||
|
|
||||||
struct JoinInfo;
|
struct JoinInfo;
|
||||||
|
@ -36,6 +43,17 @@ public:
|
||||||
Fn<void(QString)> showToast,
|
Fn<void(QString)> showToast,
|
||||||
Fn<void(JoinInfo)> done);
|
Fn<void(JoinInfo)> done);
|
||||||
|
|
||||||
|
static void FillRtmpRows(
|
||||||
|
not_null<Ui::VerticalLayout*> container,
|
||||||
|
bool divider,
|
||||||
|
Fn<void(object_ptr<Ui::BoxContent>)> showBox,
|
||||||
|
Fn<void(QString)> showToast,
|
||||||
|
rpl::producer<StartRtmpProcess::Data> &&data,
|
||||||
|
const style::FlatLabel *labelStyle,
|
||||||
|
const style::IconButton *showButtonStyle,
|
||||||
|
const style::FlatLabel *subsectionTitleStyle,
|
||||||
|
const style::RoundButton *attentionButtonStyle);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void requestUrl(bool revoke);
|
void requestUrl(bool revoke);
|
||||||
void processUrl(Data data);
|
void processUrl(Data data);
|
||||||
|
|
|
@ -33,6 +33,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "data/data_channel.h"
|
#include "data/data_channel.h"
|
||||||
#include "data/data_chat.h"
|
#include "data/data_chat.h"
|
||||||
#include "data/data_group_call.h"
|
#include "data/data_group_call.h"
|
||||||
|
#include "calls/group/calls_group_rtmp.h"
|
||||||
|
#include "ui/toast/toast.h"
|
||||||
#include "data/data_changes.h"
|
#include "data/data_changes.h"
|
||||||
#include "core/application.h"
|
#include "core/application.h"
|
||||||
#include "ui/boxes/single_choice_box.h"
|
#include "ui/boxes/single_choice_box.h"
|
||||||
|
@ -625,6 +627,27 @@ void SettingsBox(
|
||||||
st::groupCallSettingsButton
|
st::groupCallSettingsButton
|
||||||
)->addClickHandler(std::move(shareLink));
|
)->addClickHandler(std::move(shareLink));
|
||||||
}
|
}
|
||||||
|
if (rtmp) {
|
||||||
|
StartRtmpProcess::FillRtmpRows(
|
||||||
|
box->verticalLayout(),
|
||||||
|
false,
|
||||||
|
[=](object_ptr<Ui::BoxContent> &&object) {
|
||||||
|
box->getDelegate()->show(std::move(object));
|
||||||
|
},
|
||||||
|
[=](QString text) {
|
||||||
|
Ui::Toast::Show(
|
||||||
|
box->getDelegate()->outerContainer(),
|
||||||
|
text);
|
||||||
|
},
|
||||||
|
rpl::single<StartRtmpProcess::Data>({
|
||||||
|
call->rtmpUrl(),
|
||||||
|
call->rtmpKey()
|
||||||
|
}),
|
||||||
|
&st::groupCallBoxLabel,
|
||||||
|
&st::groupCallSettingsRtmpShowButton,
|
||||||
|
&st::groupCallSubsectionTitle,
|
||||||
|
&st::groupCallAttentionBoxButton);
|
||||||
|
}
|
||||||
|
|
||||||
if (peer->canManageGroupCall()) {
|
if (peer->canManageGroupCall()) {
|
||||||
AddButton(
|
AddButton(
|
||||||
|
|
Loading…
Add table
Reference in a new issue