mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 22:54:01 +02:00
Allow sharing link from confcall.
This commit is contained in:
parent
0d8e5b139b
commit
9f3f715527
13 changed files with 226 additions and 53 deletions
|
@ -4755,6 +4755,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_group_call_also_end_channel" = "End live stream";
|
"lng_group_call_also_end_channel" = "End live stream";
|
||||||
"lng_group_call_settings_title" = "Settings";
|
"lng_group_call_settings_title" = "Settings";
|
||||||
"lng_group_call_invite" = "Invite Members";
|
"lng_group_call_invite" = "Invite Members";
|
||||||
|
"lng_group_call_invite_conf" = "Add People";
|
||||||
"lng_group_call_invited_status" = "invited";
|
"lng_group_call_invited_status" = "invited";
|
||||||
"lng_group_call_muted_by_me_status" = "muted for you";
|
"lng_group_call_muted_by_me_status" = "muted for you";
|
||||||
"lng_group_call_invite_title" = "Invite members";
|
"lng_group_call_invite_title" = "Invite members";
|
||||||
|
|
|
@ -804,6 +804,7 @@ groupCallAddMember: SettingsButton(defaultSettingsButton) {
|
||||||
ripple: groupCallRipple;
|
ripple: groupCallRipple;
|
||||||
}
|
}
|
||||||
groupCallAddMemberIcon: icon {{ "info/info_add_member", groupCallMemberInactiveIcon, point(0px, 3px) }};
|
groupCallAddMemberIcon: icon {{ "info/info_add_member", groupCallMemberInactiveIcon, point(0px, 3px) }};
|
||||||
|
groupCallShareLinkIcon: icon {{ "menu/links_profile", groupCallMemberInactiveIcon, point(4px, 3px) }};
|
||||||
groupCallSubtitleLabel: FlatLabel(defaultFlatLabel) {
|
groupCallSubtitleLabel: FlatLabel(defaultFlatLabel) {
|
||||||
maxHeight: 18px;
|
maxHeight: 18px;
|
||||||
textFg: groupCallMemberNotJoinedStatus;
|
textFg: groupCallMemberNotJoinedStatus;
|
||||||
|
@ -1489,12 +1490,15 @@ confcallLinkButton: RoundButton(defaultActiveButton) {
|
||||||
textTop: 12px;
|
textTop: 12px;
|
||||||
style: semiboldTextStyle;
|
style: semiboldTextStyle;
|
||||||
}
|
}
|
||||||
confcallLinkBox: Box(defaultBox) {
|
confcallLinkBoxInitial: Box(defaultBox) {
|
||||||
buttonPadding: margins(12px, 11px, 24px, 96px);
|
buttonPadding: margins(12px, 11px, 24px, 96px);
|
||||||
buttonHeight: 42px;
|
buttonHeight: 42px;
|
||||||
button: confcallLinkButton;
|
button: confcallLinkButton;
|
||||||
shadowIgnoreTopSkip: true;
|
shadowIgnoreTopSkip: true;
|
||||||
}
|
}
|
||||||
|
confcallLinkBox: Box(confcallLinkBoxInitial) {
|
||||||
|
buttonPadding: margins(12px, 11px, 24px, 24px);
|
||||||
|
}
|
||||||
confcallLinkCopyButton: RoundButton(confcallLinkButton) {
|
confcallLinkCopyButton: RoundButton(confcallLinkButton) {
|
||||||
icon: icon {{ "info/edit/links_copy", activeButtonFg }};
|
icon: icon {{ "info/edit/links_copy", activeButtonFg }};
|
||||||
iconOver: icon {{ "info/edit/links_copy", activeButtonFgOver }};
|
iconOver: icon {{ "info/edit/links_copy", activeButtonFgOver }};
|
||||||
|
@ -1516,3 +1520,21 @@ confcallLinkFooterOr: FlatLabel(confcallLinkCenteredText) {
|
||||||
confcallLinkFooterOrTop: 12px;
|
confcallLinkFooterOrTop: 12px;
|
||||||
confcallLinkFooterOrSkip: 8px;
|
confcallLinkFooterOrSkip: 8px;
|
||||||
confcallLinkFooterOrLineTop: 9px;
|
confcallLinkFooterOrLineTop: 9px;
|
||||||
|
|
||||||
|
groupCallLinkBox: Box(confcallLinkBox) {
|
||||||
|
bg: groupCallMembersBg;
|
||||||
|
title: FlatLabel(boxTitle) {
|
||||||
|
textFg: groupCallMembersFg;
|
||||||
|
}
|
||||||
|
titleAdditionalFg: groupCallMemberNotJoinedStatus;
|
||||||
|
}
|
||||||
|
groupCallLinkCenteredText: FlatLabel(confcallLinkCenteredText) {
|
||||||
|
textFg: groupCallMembersFg;
|
||||||
|
}
|
||||||
|
groupCallLinkPreview: InputField(defaultInputField) {
|
||||||
|
textBg: groupCallMembersBgOver;
|
||||||
|
textFg: groupCallMembersFg;
|
||||||
|
textMargins: margins(12px, 8px, 30px, 5px);
|
||||||
|
style: defaultTextStyle;
|
||||||
|
heightMin: 35px;
|
||||||
|
}
|
||||||
|
|
|
@ -1153,13 +1153,17 @@ void GroupCall::setRtmpInfo(const Calls::Group::RtmpInfo &value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Data::GroupCall *GroupCall::lookupReal() const {
|
Data::GroupCall *GroupCall::lookupReal() const {
|
||||||
if (_conferenceCall) {
|
if (const auto conference = _conferenceCall.get()) {
|
||||||
return _conferenceCall.get();
|
return conference;
|
||||||
}
|
}
|
||||||
const auto real = _peer->groupCall();
|
const auto real = _peer->groupCall();
|
||||||
return (real && real->id() == _id) ? real : nullptr;
|
return (real && real->id() == _id) ? real : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<Data::GroupCall> GroupCall::conferenceCall() const {
|
||||||
|
return _conferenceCall;
|
||||||
|
}
|
||||||
|
|
||||||
rpl::producer<not_null<Data::GroupCall*>> GroupCall::real() const {
|
rpl::producer<not_null<Data::GroupCall*>> GroupCall::real() const {
|
||||||
if (const auto real = lookupReal()) {
|
if (const auto real = lookupReal()) {
|
||||||
return rpl::single(not_null{ real });
|
return rpl::single(not_null{ real });
|
||||||
|
|
|
@ -256,6 +256,7 @@ public:
|
||||||
void setRtmpInfo(const Group::RtmpInfo &value);
|
void setRtmpInfo(const Group::RtmpInfo &value);
|
||||||
|
|
||||||
[[nodiscard]] Data::GroupCall *lookupReal() const;
|
[[nodiscard]] Data::GroupCall *lookupReal() const;
|
||||||
|
[[nodiscard]] std::shared_ptr<Data::GroupCall> conferenceCall() const;
|
||||||
[[nodiscard]] rpl::producer<not_null<Data::GroupCall*>> real() const;
|
[[nodiscard]] rpl::producer<not_null<Data::GroupCall*>> real() const;
|
||||||
[[nodiscard]] rpl::producer<QByteArray> emojiHashValue() const;
|
[[nodiscard]] rpl::producer<QByteArray> emojiHashValue() const;
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#include "calls/group/calls_group_common.h"
|
#include "calls/group/calls_group_common.h"
|
||||||
|
|
||||||
|
#include "apiwrap.h"
|
||||||
#include "base/platform/base_platform_info.h"
|
#include "base/platform/base_platform_info.h"
|
||||||
#include "boxes/share_box.h"
|
#include "boxes/share_box.h"
|
||||||
#include "core/local_url_handlers.h"
|
#include "core/local_url_handlers.h"
|
||||||
|
@ -19,8 +20,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/text/text_utilities.h"
|
#include "ui/text/text_utilities.h"
|
||||||
#include "ui/vertical_list.h"
|
#include "ui/vertical_list.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
|
#include "main/main_session.h"
|
||||||
#include "window/window_session_controller.h"
|
#include "window/window_session_controller.h"
|
||||||
#include "styles/style_layers.h"
|
#include "styles/style_layers.h"
|
||||||
|
#include "styles/style_media_view.h"
|
||||||
#include "styles/style_calls.h"
|
#include "styles/style_calls.h"
|
||||||
#include "styles/style_chat.h"
|
#include "styles/style_chat.h"
|
||||||
|
|
||||||
|
@ -86,16 +89,34 @@ void ConferenceCallJoinConfirm(
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ConferenceCallLinkStyleOverrides DarkConferenceCallLinkStyle() {
|
||||||
|
return {
|
||||||
|
.box = &st::groupCallLinkBox,
|
||||||
|
.close = &st::storiesStealthBoxClose,
|
||||||
|
.centerLabel = &st::groupCallLinkCenteredText,
|
||||||
|
.linkPreview = &st::groupCallLinkPreview,
|
||||||
|
.shareBox = std::make_shared<ShareBoxStyleOverrides>(
|
||||||
|
DarkShareBoxStyle()),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
void ShowConferenceCallLinkBox(
|
void ShowConferenceCallLinkBox(
|
||||||
not_null<Window::SessionController*> controller,
|
std::shared_ptr<Main::SessionShow> show,
|
||||||
std::shared_ptr<Data::GroupCall> call,
|
std::shared_ptr<Data::GroupCall> call,
|
||||||
const QString &link,
|
const QString &link,
|
||||||
bool initial) {
|
ConferenceCallLinkArgs &&args) {
|
||||||
controller->show(Box([=](not_null<Ui::GenericBox*> box) {
|
const auto st = args.st;
|
||||||
box->setStyle(st::confcallLinkBox);
|
const auto initial = args.initial;
|
||||||
|
const auto weakWindow = args.weakWindow;
|
||||||
|
show->showBox(Box([=](not_null<Ui::GenericBox*> box) {
|
||||||
|
box->setStyle(st.box
|
||||||
|
? *st.box
|
||||||
|
: initial
|
||||||
|
? st::confcallLinkBoxInitial
|
||||||
|
: st::confcallLinkBox);
|
||||||
box->setWidth(st::boxWideWidth);
|
box->setWidth(st::boxWideWidth);
|
||||||
box->setNoContentMargin(true);
|
box->setNoContentMargin(true);
|
||||||
box->addTopButton(st::boxTitleClose, [=] {
|
box->addTopButton(st.close ? *st.close : st::boxTitleClose, [=] {
|
||||||
box->closeBox();
|
box->closeBox();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -108,19 +129,24 @@ void ShowConferenceCallLinkBox(
|
||||||
object_ptr<Ui::FlatLabel>(
|
object_ptr<Ui::FlatLabel>(
|
||||||
box,
|
box,
|
||||||
tr::lng_confcall_link_title(),
|
tr::lng_confcall_link_title(),
|
||||||
st::boxTitle)),
|
st.box ? st.box->title : st::boxTitle)),
|
||||||
st::boxRowPadding + st::confcallLinkTitlePadding);
|
st::boxRowPadding + st::confcallLinkTitlePadding);
|
||||||
box->addRow(
|
box->addRow(
|
||||||
object_ptr<Ui::FlatLabel>(
|
object_ptr<Ui::FlatLabel>(
|
||||||
box,
|
box,
|
||||||
tr::lng_confcall_link_about(),
|
tr::lng_confcall_link_about(),
|
||||||
st::confcallLinkCenteredText),
|
(st.centerLabel
|
||||||
|
? *st.centerLabel
|
||||||
|
: st::confcallLinkCenteredText)),
|
||||||
st::boxRowPadding
|
st::boxRowPadding
|
||||||
)->setTryMakeSimilarLines(true);
|
)->setTryMakeSimilarLines(true);
|
||||||
|
|
||||||
Ui::AddSkip(box->verticalLayout(), st::defaultVerticalListSkip * 2);
|
Ui::AddSkip(box->verticalLayout(), st::defaultVerticalListSkip * 2);
|
||||||
const auto preview = box->addRow(
|
const auto preview = box->addRow(
|
||||||
Info::BotStarRef::MakeLinkLabel(box, link));
|
Info::BotStarRef::MakeLinkLabel(
|
||||||
|
box,
|
||||||
|
link,
|
||||||
|
st.linkPreview));
|
||||||
Ui::AddSkip(box->verticalLayout());
|
Ui::AddSkip(box->verticalLayout());
|
||||||
|
|
||||||
const auto copyCallback = [=] {
|
const auto copyCallback = [=] {
|
||||||
|
@ -128,7 +154,10 @@ void ShowConferenceCallLinkBox(
|
||||||
box->uiShow()->showToast(tr::lng_username_copied(tr::now));
|
box->uiShow()->showToast(tr::lng_username_copied(tr::now));
|
||||||
};
|
};
|
||||||
const auto shareCallback = [=] {
|
const auto shareCallback = [=] {
|
||||||
FastShareLink(controller, link);
|
FastShareLink(
|
||||||
|
show,
|
||||||
|
link,
|
||||||
|
st.shareBox ? *st.shareBox : ShareBoxStyleOverrides());
|
||||||
};
|
};
|
||||||
preview->setClickedCallback(copyCallback);
|
preview->setClickedCallback(copyCallback);
|
||||||
[[maybe_unused]] const auto share = box->addButton(
|
[[maybe_unused]] const auto share = box->addButton(
|
||||||
|
@ -155,6 +184,10 @@ void ShowConferenceCallLinkBox(
|
||||||
share->moveToRight(padding.right(), share->y(), width);
|
share->moveToRight(padding.right(), share->y(), width);
|
||||||
}, box->lifetime());
|
}, box->lifetime());
|
||||||
|
|
||||||
|
if (!initial) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const auto sep = Ui::CreateChild<Ui::FlatLabel>(
|
const auto sep = Ui::CreateChild<Ui::FlatLabel>(
|
||||||
copy->parentWidget(),
|
copy->parentWidget(),
|
||||||
tr::lng_confcall_link_or(),
|
tr::lng_confcall_link_or(),
|
||||||
|
@ -180,14 +213,18 @@ void ShowConferenceCallLinkBox(
|
||||||
rpl::single(Ui::Text::IconEmoji(&st::textMoreIconEmoji)),
|
rpl::single(Ui::Text::IconEmoji(&st::textMoreIconEmoji)),
|
||||||
[](QString v) { return Ui::Text::Link(v); }),
|
[](QString v) { return Ui::Text::Link(v); }),
|
||||||
Ui::Text::WithEntities),
|
Ui::Text::WithEntities),
|
||||||
st::confcallLinkCenteredText);
|
(st.centerLabel
|
||||||
|
? *st.centerLabel
|
||||||
|
: st::confcallLinkCenteredText));
|
||||||
footer->setTryMakeSimilarLines(true);
|
footer->setTryMakeSimilarLines(true);
|
||||||
footer->setClickHandlerFilter([=](const auto &...) {
|
footer->setClickHandlerFilter([=](const auto &...) {
|
||||||
const auto local = Core::TryConvertUrlToLocal(link);
|
const auto local = Core::TryConvertUrlToLocal(link);
|
||||||
controller->resolveConferenceCall(
|
if (const auto controller = weakWindow.get()) {
|
||||||
local,
|
controller->resolveConferenceCall(
|
||||||
crl::guard(box, [=](bool ok) { if (ok) box->closeBox(); }),
|
local,
|
||||||
true);
|
crl::guard(box, [=](bool ok) { if (ok) box->closeBox(); }),
|
||||||
|
true);
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
copy->geometryValue() | rpl::start_with_next([=](QRect geometry) {
|
copy->geometryValue() | rpl::start_with_next([=](QRect geometry) {
|
||||||
|
@ -209,4 +246,33 @@ void ShowConferenceCallLinkBox(
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ExportConferenceCallLink(
|
||||||
|
std::shared_ptr<Main::SessionShow> show,
|
||||||
|
std::shared_ptr<Data::GroupCall> call,
|
||||||
|
ConferenceCallLinkArgs &&args) {
|
||||||
|
const auto session = &show->session();
|
||||||
|
const auto finished = std::move(args.finished);
|
||||||
|
|
||||||
|
using Flag = MTPphone_ExportGroupCallInvite::Flag;
|
||||||
|
session->api().request(MTPphone_ExportGroupCallInvite(
|
||||||
|
MTP_flags(Flag::f_can_self_unmute),
|
||||||
|
call->input()
|
||||||
|
)).done([=](const MTPphone_ExportedGroupCallInvite &result) {
|
||||||
|
const auto link = qs(result.data().vlink());
|
||||||
|
Calls::Group::ShowConferenceCallLinkBox(
|
||||||
|
show,
|
||||||
|
call,
|
||||||
|
link,
|
||||||
|
base::duplicate(args));
|
||||||
|
if (const auto onstack = finished) {
|
||||||
|
finished(true);
|
||||||
|
}
|
||||||
|
}).fail([=](const MTP::Error &error) {
|
||||||
|
show->showToast(error.type());
|
||||||
|
if (const auto onstack = finished) {
|
||||||
|
finished(false);
|
||||||
|
}
|
||||||
|
}).send();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Calls::Group
|
} // namespace Calls::Group
|
||||||
|
|
|
@ -8,13 +8,26 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "base/object_ptr.h"
|
#include "base/object_ptr.h"
|
||||||
|
#include "base/weak_ptr.h"
|
||||||
|
|
||||||
class UserData;
|
class UserData;
|
||||||
|
struct ShareBoxStyleOverrides;
|
||||||
|
|
||||||
|
namespace style {
|
||||||
|
struct Box;
|
||||||
|
struct FlatLabel;
|
||||||
|
struct IconButton;
|
||||||
|
struct InputField;
|
||||||
|
} // namespace style
|
||||||
|
|
||||||
namespace Data {
|
namespace Data {
|
||||||
class GroupCall;
|
class GroupCall;
|
||||||
} // namespace Data
|
} // namespace Data
|
||||||
|
|
||||||
|
namespace Main {
|
||||||
|
class SessionShow;
|
||||||
|
} // namespace Main
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class Show;
|
class Show;
|
||||||
class GenericBox;
|
class GenericBox;
|
||||||
|
@ -118,10 +131,30 @@ void ConferenceCallJoinConfirm(
|
||||||
std::shared_ptr<Data::GroupCall> call,
|
std::shared_ptr<Data::GroupCall> call,
|
||||||
Fn<void()> join);
|
Fn<void()> join);
|
||||||
|
|
||||||
|
struct ConferenceCallLinkStyleOverrides {
|
||||||
|
const style::Box *box = nullptr;
|
||||||
|
const style::IconButton *close = nullptr;
|
||||||
|
const style::FlatLabel *centerLabel = nullptr;
|
||||||
|
const style::InputField *linkPreview = nullptr;
|
||||||
|
std::shared_ptr<ShareBoxStyleOverrides> shareBox;
|
||||||
|
};
|
||||||
|
[[nodiscard]] ConferenceCallLinkStyleOverrides DarkConferenceCallLinkStyle();
|
||||||
|
|
||||||
|
struct ConferenceCallLinkArgs {
|
||||||
|
bool initial = false;
|
||||||
|
Fn<void(bool)> finished;
|
||||||
|
base::weak_ptr<Window::SessionController> weakWindow = nullptr;
|
||||||
|
ConferenceCallLinkStyleOverrides st;
|
||||||
|
};
|
||||||
void ShowConferenceCallLinkBox(
|
void ShowConferenceCallLinkBox(
|
||||||
not_null<Window::SessionController*> controller,
|
std::shared_ptr<Main::SessionShow> show,
|
||||||
std::shared_ptr<Data::GroupCall> call,
|
std::shared_ptr<Data::GroupCall> call,
|
||||||
const QString &link,
|
const QString &link,
|
||||||
bool initial = false);
|
ConferenceCallLinkArgs &&args);
|
||||||
|
|
||||||
|
void ExportConferenceCallLink(
|
||||||
|
std::shared_ptr<Main::SessionShow> show,
|
||||||
|
std::shared_ptr<Data::GroupCall> call,
|
||||||
|
ConferenceCallLinkArgs &&args);
|
||||||
|
|
||||||
} // namespace Calls::Group
|
} // namespace Calls::Group
|
||||||
|
|
|
@ -1615,6 +1615,7 @@ rpl::producer<int> Members::desiredHeightValue() const {
|
||||||
return rpl::combine(
|
return rpl::combine(
|
||||||
heightValue(),
|
heightValue(),
|
||||||
_addMemberButton.value(),
|
_addMemberButton.value(),
|
||||||
|
_shareLinkButton.value(),
|
||||||
_listController->fullCountValue(),
|
_listController->fullCountValue(),
|
||||||
_mode.value()
|
_mode.value()
|
||||||
) | rpl::map([=] {
|
) | rpl::map([=] {
|
||||||
|
@ -1626,8 +1627,11 @@ void Members::setupAddMember(not_null<GroupCall*> call) {
|
||||||
using namespace rpl::mappers;
|
using namespace rpl::mappers;
|
||||||
|
|
||||||
const auto peer = call->peer();
|
const auto peer = call->peer();
|
||||||
|
const auto conference = call->conference();
|
||||||
const auto canAddByPeer = [=](not_null<PeerData*> peer) {
|
const auto canAddByPeer = [=](not_null<PeerData*> peer) {
|
||||||
if (peer->isBroadcast()) {
|
if (conference) {
|
||||||
|
return rpl::single(true) | rpl::type_erased();
|
||||||
|
} else if (peer->isBroadcast()) {
|
||||||
return rpl::single(false) | rpl::type_erased();
|
return rpl::single(false) | rpl::type_erased();
|
||||||
}
|
}
|
||||||
return rpl::combine(
|
return rpl::combine(
|
||||||
|
@ -1638,6 +1642,9 @@ void Members::setupAddMember(not_null<GroupCall*> call) {
|
||||||
}) | rpl::type_erased();
|
}) | rpl::type_erased();
|
||||||
};
|
};
|
||||||
const auto canInviteByLinkByPeer = [=](not_null<PeerData*> peer) {
|
const auto canInviteByLinkByPeer = [=](not_null<PeerData*> peer) {
|
||||||
|
if (conference) {
|
||||||
|
return rpl::single(true) | rpl::type_erased();
|
||||||
|
}
|
||||||
const auto channel = peer->asChannel();
|
const auto channel = peer->asChannel();
|
||||||
if (!channel) {
|
if (!channel) {
|
||||||
return rpl::single(false) | rpl::type_erased();
|
return rpl::single(false) | rpl::type_erased();
|
||||||
|
@ -1672,11 +1679,18 @@ void Members::setupAddMember(not_null<GroupCall*> call) {
|
||||||
_addMemberButton = nullptr;
|
_addMemberButton = nullptr;
|
||||||
updateControlsGeometry();
|
updateControlsGeometry();
|
||||||
}
|
}
|
||||||
|
if (const auto old = _shareLinkButton.current()) {
|
||||||
|
delete old;
|
||||||
|
_shareLinkButton = nullptr;
|
||||||
|
updateControlsGeometry();
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto addMember = Settings::CreateButtonWithIcon(
|
auto addMember = Settings::CreateButtonWithIcon(
|
||||||
_layout.get(),
|
_layout.get(),
|
||||||
tr::lng_group_call_invite(),
|
(conference
|
||||||
|
? tr::lng_group_call_invite_conf()
|
||||||
|
: tr::lng_group_call_invite()),
|
||||||
st::groupCallAddMember,
|
st::groupCallAddMember,
|
||||||
{ .icon = &st::groupCallAddMemberIcon });
|
{ .icon = &st::groupCallAddMemberIcon });
|
||||||
addMember->clicks(
|
addMember->clicks(
|
||||||
|
@ -1688,6 +1702,21 @@ void Members::setupAddMember(not_null<GroupCall*> call) {
|
||||||
delete _addMemberButton.current();
|
delete _addMemberButton.current();
|
||||||
_addMemberButton = addMember.data();
|
_addMemberButton = addMember.data();
|
||||||
_layout->insert(3, std::move(addMember));
|
_layout->insert(3, std::move(addMember));
|
||||||
|
if (conference) {
|
||||||
|
auto shareLink = Settings::CreateButtonWithIcon(
|
||||||
|
_layout.get(),
|
||||||
|
tr::lng_group_invite_share(),
|
||||||
|
st::groupCallAddMember,
|
||||||
|
{ .icon = &st::groupCallShareLinkIcon });
|
||||||
|
shareLink->clicks() | rpl::to_empty | rpl::start_to_stream(
|
||||||
|
_shareLinkRequests,
|
||||||
|
shareLink->lifetime());
|
||||||
|
shareLink->show();
|
||||||
|
shareLink->resizeToWidth(_layout->width());
|
||||||
|
delete _shareLinkButton.current();
|
||||||
|
_shareLinkButton = shareLink.data();
|
||||||
|
_layout->insert(4, std::move(shareLink));
|
||||||
|
}
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
|
|
||||||
updateControlsGeometry();
|
updateControlsGeometry();
|
||||||
|
|
|
@ -59,6 +59,9 @@ public:
|
||||||
[[nodiscard]] rpl::producer<> addMembersRequests() const {
|
[[nodiscard]] rpl::producer<> addMembersRequests() const {
|
||||||
return _addMemberRequests.events();
|
return _addMemberRequests.events();
|
||||||
}
|
}
|
||||||
|
[[nodiscard]] rpl::producer<> shareLinkRequests() const {
|
||||||
|
return _shareLinkRequests.events();
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] MembersRow *lookupRow(not_null<PeerData*> peer) const;
|
[[nodiscard]] MembersRow *lookupRow(not_null<PeerData*> peer) const;
|
||||||
[[nodiscard]] not_null<MembersRow*> rtmpFakeRow(
|
[[nodiscard]] not_null<MembersRow*> rtmpFakeRow(
|
||||||
|
@ -106,10 +109,12 @@ private:
|
||||||
const not_null<Ui::RpWidget*> _videoWrap;
|
const not_null<Ui::RpWidget*> _videoWrap;
|
||||||
std::unique_ptr<Viewport> _viewport;
|
std::unique_ptr<Viewport> _viewport;
|
||||||
rpl::variable<Ui::RpWidget*> _addMemberButton = nullptr;
|
rpl::variable<Ui::RpWidget*> _addMemberButton = nullptr;
|
||||||
|
rpl::variable<Ui::RpWidget*> _shareLinkButton = nullptr;
|
||||||
RpWidget *_topSkip = nullptr;
|
RpWidget *_topSkip = nullptr;
|
||||||
RpWidget *_bottomSkip = nullptr;
|
RpWidget *_bottomSkip = nullptr;
|
||||||
ListWidget *_list = nullptr;
|
ListWidget *_list = nullptr;
|
||||||
rpl::event_stream<> _addMemberRequests;
|
rpl::event_stream<> _addMemberRequests;
|
||||||
|
rpl::event_stream<> _shareLinkRequests;
|
||||||
|
|
||||||
mutable std::unique_ptr<MembersRow> _rtmpFakeRow;
|
mutable std::unique_ptr<MembersRow> _rtmpFakeRow;
|
||||||
|
|
||||||
|
|
|
@ -934,16 +934,12 @@ void Panel::setupMembers() {
|
||||||
|
|
||||||
_members->toggleMuteRequests(
|
_members->toggleMuteRequests(
|
||||||
) | rpl::start_with_next([=](MuteRequest request) {
|
) | rpl::start_with_next([=](MuteRequest request) {
|
||||||
if (_call) {
|
_call->toggleMute(request);
|
||||||
_call->toggleMute(request);
|
|
||||||
}
|
|
||||||
}, _callLifetime);
|
}, _callLifetime);
|
||||||
|
|
||||||
_members->changeVolumeRequests(
|
_members->changeVolumeRequests(
|
||||||
) | rpl::start_with_next([=](VolumeRequest request) {
|
) | rpl::start_with_next([=](VolumeRequest request) {
|
||||||
if (_call) {
|
_call->changeVolume(request);
|
||||||
_call->changeVolume(request);
|
|
||||||
}
|
|
||||||
}, _callLifetime);
|
}, _callLifetime);
|
||||||
|
|
||||||
_members->kickParticipantRequests(
|
_members->kickParticipantRequests(
|
||||||
|
@ -964,6 +960,21 @@ void Panel::setupMembers() {
|
||||||
}
|
}
|
||||||
}, _callLifetime);
|
}, _callLifetime);
|
||||||
|
|
||||||
|
const auto exporting = std::make_shared<bool>();
|
||||||
|
_members->shareLinkRequests(
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
Expects(_call->conference());
|
||||||
|
|
||||||
|
if (*exporting) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
*exporting = true;
|
||||||
|
ExportConferenceCallLink(uiShow(), _call->conferenceCall(), {
|
||||||
|
.st = DarkConferenceCallLinkStyle(),
|
||||||
|
.finished = [=](bool) { *exporting = false; },
|
||||||
|
});
|
||||||
|
}, _callLifetime);
|
||||||
|
|
||||||
_call->videoEndpointLargeValue(
|
_call->videoEndpointLargeValue(
|
||||||
) | rpl::start_with_next([=](const VideoEndpoint &large) {
|
) | rpl::start_with_next([=](const VideoEndpoint &large) {
|
||||||
if (large && mode() != PanelMode::Wide) {
|
if (large && mode() != PanelMode::Wide) {
|
||||||
|
|
|
@ -390,14 +390,16 @@ void AddFullWidthButtonFooter(
|
||||||
|
|
||||||
object_ptr<Ui::AbstractButton> MakeLinkLabel(
|
object_ptr<Ui::AbstractButton> MakeLinkLabel(
|
||||||
not_null<QWidget*> parent,
|
not_null<QWidget*> parent,
|
||||||
const QString &link) {
|
const QString &link,
|
||||||
|
const style::InputField *stOverride) {
|
||||||
|
const auto &st = stOverride ? *stOverride : st::dialogsFilter;
|
||||||
const auto text = link.startsWith(u"https://"_q)
|
const auto text = link.startsWith(u"https://"_q)
|
||||||
? link.mid(8)
|
? link.mid(8)
|
||||||
: link.startsWith(u"http://"_q)
|
: link.startsWith(u"http://"_q)
|
||||||
? link.mid(7)
|
? link.mid(7)
|
||||||
: link;
|
: link;
|
||||||
const auto margins = st::dialogsFilter.textMargins;
|
const auto margins = st.textMargins;
|
||||||
const auto height = st::dialogsFilter.heightMin;
|
const auto height = st.heightMin;
|
||||||
const auto skip = margins.left();
|
const auto skip = margins.left();
|
||||||
|
|
||||||
auto result = object_ptr<Ui::AbstractButton>(parent);
|
auto result = object_ptr<Ui::AbstractButton>(parent);
|
||||||
|
@ -408,12 +410,12 @@ object_ptr<Ui::AbstractButton> MakeLinkLabel(
|
||||||
auto p = QPainter(raw);
|
auto p = QPainter(raw);
|
||||||
auto hq = PainterHighQualityEnabler(p);
|
auto hq = PainterHighQualityEnabler(p);
|
||||||
p.setPen(Qt::NoPen);
|
p.setPen(Qt::NoPen);
|
||||||
p.setBrush(st::dialogsFilter.textBg);
|
p.setBrush(st.textBg);
|
||||||
const auto radius = st::roundRadiusLarge;
|
const auto radius = st::roundRadiusLarge;
|
||||||
p.drawRoundedRect(0, 0, raw->width(), height, radius, radius);
|
p.drawRoundedRect(0, 0, raw->width(), height, radius, radius);
|
||||||
|
|
||||||
const auto font = st::dialogsFilter.style.font;
|
const auto font = st.style.font;
|
||||||
p.setPen(st::dialogsFilter.textFg);
|
p.setPen(st.textFg);
|
||||||
p.setFont(font);
|
p.setFont(font);
|
||||||
const auto available = raw->width() - skip * 2;
|
const auto available = raw->width() - skip * 2;
|
||||||
p.drawText(
|
p.drawText(
|
||||||
|
@ -1065,4 +1067,4 @@ object_ptr<Ui::RpWidget> CreateLinkHeaderIcon(
|
||||||
return CreateLinkIcon(parent, session, usersCount);
|
return CreateLinkIcon(parent, session, usersCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Info::BotStarRef
|
} // namespace Info::BotStarRef
|
||||||
|
|
|
@ -21,6 +21,7 @@ class Show;
|
||||||
|
|
||||||
namespace style {
|
namespace style {
|
||||||
struct RoundButton;
|
struct RoundButton;
|
||||||
|
struct InputField;
|
||||||
} // namespace style
|
} // namespace style
|
||||||
|
|
||||||
namespace Main {
|
namespace Main {
|
||||||
|
@ -107,7 +108,8 @@ void FinishProgram(
|
||||||
|
|
||||||
[[nodiscard]] object_ptr<Ui::AbstractButton> MakeLinkLabel(
|
[[nodiscard]] object_ptr<Ui::AbstractButton> MakeLinkLabel(
|
||||||
not_null<QWidget*> parent,
|
not_null<QWidget*> parent,
|
||||||
const QString &link);
|
const QString &link,
|
||||||
|
const style::InputField *stOverride = nullptr);
|
||||||
[[nodiscard]] object_ptr<Ui::RpWidget> CreateLinkHeaderIcon(
|
[[nodiscard]] object_ptr<Ui::RpWidget> CreateLinkHeaderIcon(
|
||||||
not_null<QWidget*> parent,
|
not_null<QWidget*> parent,
|
||||||
not_null<Main::Session*> session,
|
not_null<Main::Session*> session,
|
||||||
|
|
|
@ -259,3 +259,6 @@ darkGiftTableMessage: FlatLabel(giveawayGiftMessage) {
|
||||||
textFg: groupCallMembersFg;
|
textFg: groupCallMembersFg;
|
||||||
palette: darkGiftPalette;
|
palette: darkGiftPalette;
|
||||||
}
|
}
|
||||||
|
darkGiftCodeLink: FlatLabel(giveawayGiftCodeLink) {
|
||||||
|
textFg: mediaviewMenuFg;
|
||||||
|
}
|
||||||
|
|
|
@ -123,7 +123,7 @@ constexpr auto kPlayStatusLimit = 2;
|
||||||
(height - st::inviteViaLinkIcon.height()) / 2);
|
(height - st::inviteViaLinkIcon.height()) / 2);
|
||||||
}, icon->lifetime());
|
}, icon->lifetime());
|
||||||
|
|
||||||
const auto creating = result->lifetime().make_state<int32>();
|
const auto creating = std::make_shared<int32>();
|
||||||
result->setClickedCallback([=] {
|
result->setClickedCallback([=] {
|
||||||
if (*creating) {
|
if (*creating) {
|
||||||
return;
|
return;
|
||||||
|
@ -143,25 +143,19 @@ constexpr auto kPlayStatusLimit = 2;
|
||||||
false, // rtmp
|
false, // rtmp
|
||||||
true); // conference
|
true); // conference
|
||||||
call->processFullCall(result);
|
call->processFullCall(result);
|
||||||
using Flag = MTPphone_ExportGroupCallInvite::Flag;
|
const auto finished = [=](bool ok) {
|
||||||
session->api().request(MTPphone_ExportGroupCallInvite(
|
if (!ok) {
|
||||||
MTP_flags(Flag::f_can_self_unmute),
|
*creating = 0;
|
||||||
MTP_inputGroupCall(data.vid(), data.vaccess_hash())
|
} else if (const auto onstack = done) {
|
||||||
)).done(crl::guard(controller, [=](
|
|
||||||
const MTPphone_ExportedGroupCallInvite &result) {
|
|
||||||
const auto link = qs(result.data().vlink());
|
|
||||||
Calls::Group::ShowConferenceCallLinkBox(
|
|
||||||
controller,
|
|
||||||
call,
|
|
||||||
link,
|
|
||||||
true);
|
|
||||||
if (const auto onstack = done) {
|
|
||||||
onstack();
|
onstack();
|
||||||
}
|
}
|
||||||
})).fail(crl::guard(controller, [=](const MTP::Error &error) {
|
};
|
||||||
show->showToast(error.type());
|
const auto show = controller->uiShow();
|
||||||
*creating = 0;
|
Calls::Group::ExportConferenceCallLink(show, call, {
|
||||||
})).send();
|
.initial = true,
|
||||||
|
.finished = finished,
|
||||||
|
.weakWindow = controller,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
})).fail(crl::guard(controller, [=](const MTP::Error &error) {
|
})).fail(crl::guard(controller, [=](const MTP::Error &error) {
|
||||||
show->showToast(error.type());
|
show->showToast(error.type());
|
||||||
|
|
Loading…
Add table
Reference in a new issue