mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-15 21:57:10 +02:00
Allow discarding group call when leaving.
This commit is contained in:
parent
e66a72876c
commit
abb81c764e
14 changed files with 204 additions and 36 deletions
|
@ -270,6 +270,8 @@ PRIVATE
|
|||
calls/calls_group_members.h
|
||||
calls/calls_group_panel.cpp
|
||||
calls/calls_group_panel.h
|
||||
calls/calls_group_settings.cpp
|
||||
calls/calls_group_settings.h
|
||||
calls/calls_emoji_fingerprint.cpp
|
||||
calls/calls_emoji_fingerprint.h
|
||||
calls/calls_instance.cpp
|
||||
|
|
|
@ -1824,6 +1824,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
"lng_group_call_leave_sure" = "Are you sure you want to leave this voice chat?";
|
||||
"lng_group_call_also_end" = "End voice chat";
|
||||
"lng_group_call_settings_title" = "Settings";
|
||||
"lng_group_call_new_muted" = "Mute new members";
|
||||
"lng_group_call_speakers" = "Speakers";
|
||||
"lng_group_call_microphone" = "Microphone";
|
||||
"lng_group_call_share" = "Share Invite Link";
|
||||
|
|
|
@ -81,7 +81,7 @@ void GroupCall::setState(State state) {
|
|||
|
||||
void GroupCall::start() {
|
||||
const auto randomId = rand_value<int32>();
|
||||
_api.request(MTPphone_CreateGroupCall(
|
||||
_createRequestId = _api.request(MTPphone_CreateGroupCall(
|
||||
_channel->inputChannel,
|
||||
MTP_int(randomId)
|
||||
)).done([=](const MTPUpdates &result) {
|
||||
|
@ -155,7 +155,9 @@ void GroupCall::rejoin() {
|
|||
MTP_dataJSON(MTP_bytes(json))
|
||||
)).done([=](const MTPUpdates &updates) {
|
||||
_mySsrc = ssrc;
|
||||
setState(State::Joined);
|
||||
setState(_instanceConnected
|
||||
? State::Joined
|
||||
: State::Connecting);
|
||||
applySelfInCallLocally();
|
||||
|
||||
if (_muted.current() != muted) {
|
||||
|
@ -212,6 +214,24 @@ void GroupCall::hangup() {
|
|||
finish(FinishType::Ended);
|
||||
}
|
||||
|
||||
void GroupCall::discard() {
|
||||
if (!_id) {
|
||||
_api.request(_createRequestId).cancel();
|
||||
hangup();
|
||||
return;
|
||||
}
|
||||
_api.request(MTPphone_DiscardGroupCall(
|
||||
inputCall()
|
||||
)).done([=](const MTPUpdates &result) {
|
||||
// Here 'this' could be destroyed by updates, so we set Ended after
|
||||
// updates being handled, but in a guarded way.
|
||||
crl::on_main(this, [=] { hangup(); });
|
||||
_channel->session().api().applyUpdates(result);
|
||||
}).fail([=](const RPCError &error) {
|
||||
hangup();
|
||||
}).send();
|
||||
}
|
||||
|
||||
void GroupCall::finish(FinishType type) {
|
||||
Expects(type != FinishType::None);
|
||||
|
||||
|
@ -330,7 +350,7 @@ void GroupCall::handleUpdate(const MTPGroupCall &call) {
|
|||
|
||||
void GroupCall::handleUpdate(const MTPDupdateGroupCallParticipants &data) {
|
||||
const auto state = _state.current();
|
||||
if (state != State::Joined) {
|
||||
if (state != State::Joined && state != State::Connecting) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -368,7 +388,8 @@ void GroupCall::createAndStartController() {
|
|||
tgcalls::GroupInstanceDescriptor descriptor = {
|
||||
.config = tgcalls::GroupConfig{
|
||||
},
|
||||
.networkStateUpdated = [=](bool) {
|
||||
.networkStateUpdated = [=](bool connected) {
|
||||
crl::on_main(weak, [=] { setInstanceConnected(connected); });
|
||||
},
|
||||
.audioLevelsUpdated = [=](const AudioLevels &data) {
|
||||
crl::on_main(weak, [=] { audioLevelsUpdated(data); });
|
||||
|
@ -432,6 +453,18 @@ void GroupCall::audioLevelsUpdated(
|
|||
}
|
||||
}
|
||||
|
||||
void GroupCall::setInstanceConnected(bool connected) {
|
||||
if (_instanceConnected == connected) {
|
||||
return;
|
||||
}
|
||||
_instanceConnected = connected;
|
||||
if (state() == State::Connecting && connected) {
|
||||
setState(State::Joined);
|
||||
} else if (state() == State::Joined && !connected) {
|
||||
setState(State::Connecting);
|
||||
}
|
||||
}
|
||||
|
||||
void GroupCall::sendMutedUpdate() {
|
||||
_api.request(_updateMuteRequestId).cancel();
|
||||
_updateMuteRequestId = _api.request(MTPphone_EditGroupCallMember(
|
||||
|
@ -446,7 +479,8 @@ void GroupCall::sendMutedUpdate() {
|
|||
}).fail([=](const RPCError &error) {
|
||||
_updateMuteRequestId = 0;
|
||||
if (error.type() == u"GROUP_CALL_FORBIDDEN"_q
|
||||
&& _state.current() == State::Joined) {
|
||||
&& (_state.current() == State::Joined
|
||||
|| _state.current() == State::Connecting)) {
|
||||
setState(State::Joining);
|
||||
rejoin();
|
||||
}
|
||||
|
@ -475,7 +509,8 @@ void GroupCall::toggleMute(not_null<UserData*> user, bool mute) {
|
|||
_channel->session().api().applyUpdates(result);
|
||||
}).fail([=](const RPCError &error) {
|
||||
if (error.type() == u"GROUP_CALL_FORBIDDEN"_q
|
||||
&& _state.current() == State::Joined) {
|
||||
&& (_state.current() == State::Joined
|
||||
|| _state.current() == State::Connecting)) {
|
||||
setState(State::Joining);
|
||||
rejoin();
|
||||
}
|
||||
|
|
|
@ -57,6 +57,7 @@ public:
|
|||
|
||||
void start();
|
||||
void hangup();
|
||||
void discard();
|
||||
void join(const MTPInputGroupCall &inputCall);
|
||||
void handleUpdate(const MTPGroupCall &call);
|
||||
void handleUpdate(const MTPDupdateGroupCallParticipants &data);
|
||||
|
@ -68,13 +69,11 @@ public:
|
|||
[[nodiscard]] rpl::producer<MuteState> mutedValue() const {
|
||||
return _muted.value();
|
||||
}
|
||||
[[nodiscard]] bool joined() const {
|
||||
return (_state.current() == State::Joined);
|
||||
}
|
||||
|
||||
enum State {
|
||||
Creating,
|
||||
Joining,
|
||||
Connecting,
|
||||
Joined,
|
||||
FailedHangingUp,
|
||||
Failed,
|
||||
|
@ -123,6 +122,7 @@ private:
|
|||
void myLevelUpdated(float level);
|
||||
void audioLevelsUpdated(
|
||||
const std::vector<std::pair<std::uint32_t, float>> &data);
|
||||
void setInstanceConnected(bool connected);
|
||||
|
||||
[[nodiscard]] MTPInputGroupCall inputCall() const;
|
||||
|
||||
|
@ -130,6 +130,7 @@ private:
|
|||
const not_null<ChannelData*> _channel;
|
||||
MTP::Sender _api;
|
||||
rpl::variable<State> _state = State::Creating;
|
||||
bool _instanceConnected = false;
|
||||
|
||||
rpl::variable<MuteState> _muted = MuteState::Muted;
|
||||
bool _acceptFields = false;
|
||||
|
@ -137,6 +138,7 @@ private:
|
|||
uint64 _id = 0;
|
||||
uint64 _accessHash = 0;
|
||||
uint32 _mySsrc = 0;
|
||||
mtpRequestId _createRequestId = 0;
|
||||
mtpRequestId _updateMuteRequestId = 0;
|
||||
|
||||
std::unique_ptr<tgcalls::GroupInstanceImpl> _instance;
|
||||
|
|
|
@ -27,7 +27,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
namespace Calls {
|
||||
namespace {
|
||||
|
||||
constexpr auto kLevelThreshold = 0.01;
|
||||
constexpr auto kLevelThreshold = 0.2;
|
||||
constexpr auto kLevelActiveTimeout = crl::time(1000);
|
||||
|
||||
struct UpdateLevelResult {
|
||||
|
|
|
@ -8,17 +8,21 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "calls/calls_group_panel.h"
|
||||
|
||||
#include "calls/calls_group_members.h"
|
||||
#include "calls/calls_group_settings.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/window.h"
|
||||
#include "ui/widgets/call_button.h"
|
||||
#include "ui/widgets/call_mute_button.h"
|
||||
#include "ui/widgets/checkbox.h"
|
||||
#include "ui/layers/layer_manager.h"
|
||||
#include "boxes/confirm_box.h"
|
||||
#include "ui/layers/generic_box.h"
|
||||
#include "core/application.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "data/data_channel.h"
|
||||
#include "base/event_filter.h"
|
||||
#include "app.h"
|
||||
#include "styles/style_calls.h"
|
||||
#include "styles/style_layers.h"
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#include "ui/platform/win/ui_window_title_win.h"
|
||||
|
@ -30,6 +34,44 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
|
||||
namespace Calls {
|
||||
|
||||
void LeaveGroupCallBox(
|
||||
not_null<Ui::GenericBox*> box,
|
||||
not_null<GroupCall*> call,
|
||||
bool discardChecked,
|
||||
BoxContext context) {
|
||||
box->setTitle(tr::lng_group_call_leave_title());
|
||||
box->addRow(object_ptr<Ui::FlatLabel>(
|
||||
box.get(),
|
||||
tr::lng_group_call_leave_sure(),
|
||||
st::boxLabel));
|
||||
const auto discard = call->channel()->canManageCall()
|
||||
? box->addRow(object_ptr<Ui::Checkbox>(
|
||||
box.get(),
|
||||
tr::lng_group_call_end(),
|
||||
discardChecked,
|
||||
st::defaultBoxCheckbox),
|
||||
style::margins(
|
||||
st::boxRowPadding.left(),
|
||||
st::boxRowPadding.left(),
|
||||
st::boxRowPadding.right(),
|
||||
st::boxRowPadding.bottom()))
|
||||
: nullptr;
|
||||
const auto weak = base::make_weak(call.get());
|
||||
box->addButton(tr::lng_group_call_leave(), [=] {
|
||||
const auto discardCall = (discard && discard->checked());
|
||||
box->closeBox();
|
||||
|
||||
if (!weak) {
|
||||
return;
|
||||
} else if (discardCall) {
|
||||
call->discard();
|
||||
} else {
|
||||
call->hangup();
|
||||
}
|
||||
});
|
||||
box->addButton(tr::lng_cancel(), [=] { box->closeBox(); });
|
||||
}
|
||||
|
||||
GroupPanel::GroupPanel(not_null<GroupCall*> call)
|
||||
: _call(call)
|
||||
, _channel(call->channel())
|
||||
|
@ -96,7 +138,10 @@ void GroupPanel::initWindow() {
|
|||
return Flag::None | Flag(0);
|
||||
}
|
||||
#endif // Q_OS_WIN
|
||||
const auto inControls = false;
|
||||
const auto inControls = _settings->geometry().contains(widgetPoint)
|
||||
|| _mute->innerGeometry().contains(widgetPoint)
|
||||
|| _hangup->geometry().contains(widgetPoint)
|
||||
|| _members->geometry().contains(widgetPoint);
|
||||
return inControls
|
||||
? Flag::None
|
||||
: (Flag::Move | Flag::Maximize);
|
||||
|
@ -117,6 +162,21 @@ void GroupPanel::initWidget() {
|
|||
}, widget()->lifetime());
|
||||
}
|
||||
|
||||
void GroupPanel::copyShareLink() {
|
||||
|
||||
}
|
||||
|
||||
void GroupPanel::hangup(bool discardCallChecked) {
|
||||
if (!_call) {
|
||||
return;
|
||||
}
|
||||
_layerBg->showBox(Box(
|
||||
LeaveGroupCallBox,
|
||||
_call,
|
||||
discardCallChecked,
|
||||
BoxContext::GroupCallPanel));
|
||||
}
|
||||
|
||||
void GroupPanel::initControls() {
|
||||
_mute->clicks(
|
||||
) | rpl::filter([=](Qt::MouseButton button) {
|
||||
|
@ -129,13 +189,12 @@ void GroupPanel::initControls() {
|
|||
}
|
||||
}, _mute->lifetime());
|
||||
|
||||
_hangup->setClickedCallback([=] {
|
||||
_layerBg->showBox(Box<ConfirmBox>(
|
||||
tr::lng_group_call_leave_sure(tr::now),
|
||||
tr::lng_group_call_leave(tr::now),
|
||||
[=] { if (_call) _call->hangup(); }));
|
||||
});
|
||||
_hangup->setClickedCallback([=] { hangup(false); });
|
||||
_settings->setClickedCallback([=] {
|
||||
_layerBg->showBox(Box(
|
||||
GroupCallSettingsBox,
|
||||
[=] { copyShareLink(); },
|
||||
[=] { hangup(true); }));
|
||||
});
|
||||
|
||||
_settings->setText(tr::lng_menu_settings());
|
||||
|
@ -176,7 +235,9 @@ void GroupPanel::initWithCall(GroupCall *call) {
|
|||
rpl::combine(
|
||||
_call->mutedValue(),
|
||||
_call->stateValue() | rpl::map(
|
||||
_1 == State::Creating || _1 == State::Joining
|
||||
_1 == State::Creating
|
||||
|| _1 == State::Joining
|
||||
|| _1 == State::Connecting
|
||||
)
|
||||
) | rpl::start_with_next([=](MuteState mute, bool connecting) {
|
||||
_mute->setState(Ui::CallMuteButtonState{
|
||||
|
|
|
@ -32,6 +32,7 @@ template <typename Widget>
|
|||
class PaddingWrap;
|
||||
class Window;
|
||||
class ScrollArea;
|
||||
class GenericBox;
|
||||
class LayerManager;
|
||||
namespace Platform {
|
||||
class TitleControls;
|
||||
|
@ -50,6 +51,17 @@ class SignalBars;
|
|||
|
||||
class GroupMembers;
|
||||
|
||||
enum class BoxContext {
|
||||
GroupCallPanel,
|
||||
MainWindow,
|
||||
};
|
||||
|
||||
void LeaveGroupCallBox(
|
||||
not_null<Ui::GenericBox*> box,
|
||||
not_null<GroupCall*> call,
|
||||
bool discardChecked,
|
||||
BoxContext context);
|
||||
|
||||
class GroupPanel final {
|
||||
public:
|
||||
GroupPanel(not_null<GroupCall*> call);
|
||||
|
@ -77,6 +89,9 @@ private:
|
|||
void updateControlsGeometry();
|
||||
void showControls();
|
||||
|
||||
void copyShareLink();
|
||||
void hangup(bool discardCallChecked);
|
||||
|
||||
[[nodiscard]] int computeMembersListTop() const;
|
||||
[[nodiscard]] std::optional<QRect> computeTitleRect() const;
|
||||
void refreshTitle();
|
||||
|
|
34
Telegram/SourceFiles/calls/calls_group_settings.cpp
Normal file
34
Telegram/SourceFiles/calls/calls_group_settings.cpp
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "calls/calls_group_settings.h"
|
||||
|
||||
#include "ui/widgets/checkbox.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "styles/style_layers.h"
|
||||
|
||||
namespace Calls {
|
||||
|
||||
void GroupCallSettingsBox(
|
||||
not_null<Ui::GenericBox*> box,
|
||||
Fn<void()> copyShareLink,
|
||||
Fn<void()> discard) {
|
||||
box->setTitle(tr::lng_group_call_settings_title());
|
||||
//box->addRow(object_ptr<Ui::Checkbox>(
|
||||
// box.get(),
|
||||
// tr::lng_group_call_new_muted(),
|
||||
// newMuted
|
||||
// ))
|
||||
box->addButton(tr::lng_settings_save(), [=] {
|
||||
box->closeBox();
|
||||
});
|
||||
box->addButton(tr::lng_cancel(), [=] {
|
||||
box->closeBox();
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace Calls
|
19
Telegram/SourceFiles/calls/calls_group_settings.h
Normal file
19
Telegram/SourceFiles/calls/calls_group_settings.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
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 "ui/layers/generic_box.h"
|
||||
|
||||
namespace Calls {
|
||||
|
||||
void GroupCallSettingsBox(
|
||||
not_null<Ui::GenericBox*> box,
|
||||
Fn<void()> copyShareLink,
|
||||
Fn<void()> discard);
|
||||
|
||||
} // namespace Calls
|
|
@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/labels.h"
|
||||
#include "ui/layers/generic_box.h"
|
||||
#include "ui/wrap/padding_wrap.h"
|
||||
#include "ui/text/format_values.h"
|
||||
#include "lang/lang_keys.h"
|
||||
|
@ -16,6 +17,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "calls/calls_call.h"
|
||||
#include "calls/calls_instance.h"
|
||||
#include "calls/calls_signal_bars.h"
|
||||
#include "calls/calls_group_panel.h" // LeaveGroupCallBox.
|
||||
#include "data/data_user.h"
|
||||
#include "data/data_channel.h"
|
||||
#include "data/data_changes.h"
|
||||
|
@ -174,7 +176,11 @@ void TopBar::initControls() {
|
|||
if (const auto call = _call.get()) {
|
||||
call->hangup();
|
||||
} else if (const auto group = _groupCall.get()) {
|
||||
group->hangup();
|
||||
Ui::show(Box(
|
||||
LeaveGroupCallBox,
|
||||
group,
|
||||
false,
|
||||
BoxContext::MainWindow));
|
||||
}
|
||||
});
|
||||
_updateDurationTimer.setCallback([this] { updateDurationText(); });
|
||||
|
|
|
@ -86,9 +86,6 @@ void GroupCall::requestParticipants() {
|
|||
}).fail([=](const RPCError &error) {
|
||||
_fullCount = _participants.size();
|
||||
_allReceived = true;
|
||||
_channel->session().changes().peerUpdated(
|
||||
_channel,
|
||||
PeerUpdate::Flag::GroupCall);
|
||||
_participantsRequestId = 0;
|
||||
}).send();
|
||||
}
|
||||
|
@ -136,13 +133,13 @@ void GroupCall::applyCall(const MTPGroupCall &call, bool force) {
|
|||
_version = data.vversion().v;
|
||||
_fullCount = data.vparticipants_count().v;
|
||||
}, [&](const MTPDgroupCallDiscarded &data) {
|
||||
const auto changed = (_duration != data.vduration().v)
|
||||
|| !_finished;
|
||||
if (!force && !changed) {
|
||||
return;
|
||||
}
|
||||
_finished = true;
|
||||
_duration = data.vduration().v;
|
||||
const auto id = _id;
|
||||
const auto channel = _channel;
|
||||
crl::on_main(&channel->session(), [=] {
|
||||
if (channel->call() && channel->call()->id() == id) {
|
||||
channel->clearCall();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -53,8 +53,6 @@ public:
|
|||
[[nodiscard]] rpl::producer<int> fullCountValue() const;
|
||||
|
||||
void reload();
|
||||
[[nodiscard]] bool finished() const;
|
||||
[[nodiscard]] int duration() const;
|
||||
|
||||
private:
|
||||
void applyCall(const MTPGroupCall &call, bool force);
|
||||
|
@ -80,8 +78,6 @@ private:
|
|||
rpl::event_stream<ParticipantUpdate> _participantUpdates;
|
||||
rpl::event_stream<> _participantsSliceAdded;
|
||||
|
||||
int _duration = 0;
|
||||
bool _finished = false;
|
||||
bool _allReceived = false;
|
||||
|
||||
};
|
||||
|
|
|
@ -976,7 +976,7 @@ void MainWidget::setCurrentGroupCall(Calls::GroupCall *call) {
|
|||
_currentGroupCall->stateValue(
|
||||
) | rpl::start_with_next([=](Calls::GroupCall::State state) {
|
||||
using State = Calls::GroupCall::State;
|
||||
if (state == State::Joined) {
|
||||
if (state == State::Joined || state == State::Connecting) {
|
||||
createCallTopBar();
|
||||
} else {
|
||||
destroyCallTopBar();
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 962c8d89e52a8c92bc7987eba4cfaef77a3a9ebf
|
||||
Subproject commit 41bae1eba67801eb8768887100c17b7e84e7daf7
|
Loading…
Add table
Reference in a new issue