mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Add 'invited' members to voice chats.
This commit is contained in:
parent
a85be4ccd0
commit
cabd7a276b
7 changed files with 116 additions and 14 deletions
BIN
Telegram/Resources/icons/calls/group_calls_invited.png
Normal file
BIN
Telegram/Resources/icons/calls/group_calls_invited.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 665 B |
BIN
Telegram/Resources/icons/calls/group_calls_invited@2x.png
Normal file
BIN
Telegram/Resources/icons/calls/group_calls_invited@2x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
BIN
Telegram/Resources/icons/calls/group_calls_invited@3x.png
Normal file
BIN
Telegram/Resources/icons/calls/group_calls_invited@3x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.8 KiB |
|
@ -562,6 +562,8 @@ groupCallMemberColoredCrossLine: CrossLineAnimation(groupCallMemberInactiveCross
|
||||||
fg: groupCallMemberMutedIcon;
|
fg: groupCallMemberMutedIcon;
|
||||||
icon: icon {{ "calls/group_calls_unmuted", groupCallMemberActiveIcon }};
|
icon: icon {{ "calls/group_calls_unmuted", groupCallMemberActiveIcon }};
|
||||||
}
|
}
|
||||||
|
groupCallMemberInvited: icon {{ "calls/group_calls_invited", groupCallMemberInactiveIcon }};
|
||||||
|
groupCallMemberInvitedPosition: point(2px, 12px);
|
||||||
|
|
||||||
groupCallSettings: CallButton(callMicrophoneMute) {
|
groupCallSettings: CallButton(callMicrophoneMute) {
|
||||||
button: IconButton(callButton) {
|
button: IconButton(callButton) {
|
||||||
|
|
|
@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "data/data_changes.h"
|
#include "data/data_changes.h"
|
||||||
#include "data/data_group_call.h"
|
#include "data/data_group_call.h"
|
||||||
#include "data/data_peer_values.h" // Data::CanWriteValue.
|
#include "data/data_peer_values.h" // Data::CanWriteValue.
|
||||||
|
#include "data/data_session.h" // Data::Session::invitedToCallUsers.
|
||||||
#include "ui/paint/blobs.h"
|
#include "ui/paint/blobs.h"
|
||||||
#include "ui/widgets/buttons.h"
|
#include "ui/widgets/buttons.h"
|
||||||
#include "ui/widgets/scroll_area.h"
|
#include "ui/widgets/scroll_area.h"
|
||||||
|
@ -85,6 +86,7 @@ public:
|
||||||
Active,
|
Active,
|
||||||
Inactive,
|
Inactive,
|
||||||
Muted,
|
Muted,
|
||||||
|
Invited,
|
||||||
};
|
};
|
||||||
|
|
||||||
void setSkipLevelUpdate(bool value);
|
void setSkipLevelUpdate(bool value);
|
||||||
|
@ -116,7 +118,9 @@ public:
|
||||||
st::groupCallActiveButton.height);
|
st::groupCallActiveButton.height);
|
||||||
}
|
}
|
||||||
bool actionDisabled() const override {
|
bool actionDisabled() const override {
|
||||||
return peer()->isSelf() || !_delegate->rowCanMuteMembers();
|
return peer()->isSelf()
|
||||||
|
|| (_state == State::Invited)
|
||||||
|
|| !_delegate->rowCanMuteMembers();
|
||||||
}
|
}
|
||||||
QMargins actionMargins() const override {
|
QMargins actionMargins() const override {
|
||||||
return QMargins(
|
return QMargins(
|
||||||
|
@ -135,6 +139,15 @@ public:
|
||||||
|
|
||||||
auto generatePaintUserpicCallback() -> PaintRoundImageCallback override;
|
auto generatePaintUserpicCallback() -> PaintRoundImageCallback override;
|
||||||
|
|
||||||
|
void paintStatusText(
|
||||||
|
Painter &p,
|
||||||
|
const style::PeerListItem &st,
|
||||||
|
int x,
|
||||||
|
int y,
|
||||||
|
int availableWidth,
|
||||||
|
int outerWidth,
|
||||||
|
bool selected) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct BlobsAnimation {
|
struct BlobsAnimation {
|
||||||
BlobsAnimation(
|
BlobsAnimation(
|
||||||
|
@ -223,6 +236,8 @@ private:
|
||||||
[[nodiscard]] std::unique_ptr<Row> createSelfRow();
|
[[nodiscard]] std::unique_ptr<Row> createSelfRow();
|
||||||
[[nodiscard]] std::unique_ptr<Row> createRow(
|
[[nodiscard]] std::unique_ptr<Row> createRow(
|
||||||
const Data::GroupCall::Participant &participant);
|
const Data::GroupCall::Participant &participant);
|
||||||
|
[[nodiscard]] std::unique_ptr<Row> createInvitedRow(
|
||||||
|
not_null<UserData*> user);
|
||||||
|
|
||||||
void prepareRows(not_null<Data::GroupCall*> real);
|
void prepareRows(not_null<Data::GroupCall*> real);
|
||||||
//void repaintByTimer();
|
//void repaintByTimer();
|
||||||
|
@ -241,6 +256,7 @@ private:
|
||||||
Row *findRow(not_null<UserData*> user) const;
|
Row *findRow(not_null<UserData*> user) const;
|
||||||
|
|
||||||
[[nodiscard]] Data::GroupCall *resolvedRealCall() const;
|
[[nodiscard]] Data::GroupCall *resolvedRealCall() const;
|
||||||
|
void appendInvitedUsers();
|
||||||
|
|
||||||
const base::weak_ptr<GroupCall> _call;
|
const base::weak_ptr<GroupCall> _call;
|
||||||
not_null<PeerData*> _peer;
|
not_null<PeerData*> _peer;
|
||||||
|
@ -248,6 +264,7 @@ private:
|
||||||
// Use only resolvedRealCall() method, not this value directly.
|
// Use only resolvedRealCall() method, not this value directly.
|
||||||
Data::GroupCall *_realCallRawValue = nullptr;
|
Data::GroupCall *_realCallRawValue = nullptr;
|
||||||
uint64 _realId = 0;
|
uint64 _realId = 0;
|
||||||
|
bool _prepared = false;
|
||||||
|
|
||||||
rpl::event_stream<MuteRequest> _toggleMuteRequests;
|
rpl::event_stream<MuteRequest> _toggleMuteRequests;
|
||||||
rpl::event_stream<not_null<UserData*>> _kickMemberRequests;
|
rpl::event_stream<not_null<UserData*>> _kickMemberRequests;
|
||||||
|
@ -283,12 +300,7 @@ void Row::setSkipLevelUpdate(bool value) {
|
||||||
void Row::updateState(const Data::GroupCall::Participant *participant) {
|
void Row::updateState(const Data::GroupCall::Participant *participant) {
|
||||||
setSsrc(participant ? participant->ssrc : 0);
|
setSsrc(participant ? participant->ssrc : 0);
|
||||||
if (!participant) {
|
if (!participant) {
|
||||||
if (peer()->isSelf()) {
|
setState(State::Invited);
|
||||||
setCustomStatus(tr::lng_group_call_connecting(tr::now));
|
|
||||||
} else {
|
|
||||||
setCustomStatus(QString());
|
|
||||||
}
|
|
||||||
setState(State::Inactive);
|
|
||||||
setSounding(false);
|
setSounding(false);
|
||||||
setSpeaking(false);
|
setSpeaking(false);
|
||||||
} else if (!participant->muted
|
} else if (!participant->muted
|
||||||
|
@ -476,6 +488,34 @@ auto Row::generatePaintUserpicCallback() -> PaintRoundImageCallback {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Row::paintStatusText(
|
||||||
|
Painter &p,
|
||||||
|
const style::PeerListItem &st,
|
||||||
|
int x,
|
||||||
|
int y,
|
||||||
|
int availableWidth,
|
||||||
|
int outerWidth,
|
||||||
|
bool selected) {
|
||||||
|
if (_state != State::Invited) {
|
||||||
|
PeerListRow::paintStatusText(
|
||||||
|
p,
|
||||||
|
st,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
availableWidth,
|
||||||
|
outerWidth,
|
||||||
|
selected);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
p.setFont(st::normalFont);
|
||||||
|
p.setPen(st::groupCallMemberNotJoinedStatus);
|
||||||
|
p.drawTextLeft(
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
outerWidth,
|
||||||
|
peer()->isSelf() ? "connecting..." : "invited");
|
||||||
|
}
|
||||||
|
|
||||||
void Row::paintAction(
|
void Row::paintAction(
|
||||||
Painter &p,
|
Painter &p,
|
||||||
int x,
|
int x,
|
||||||
|
@ -484,6 +524,20 @@ void Row::paintAction(
|
||||||
bool selected,
|
bool selected,
|
||||||
bool actionSelected) {
|
bool actionSelected) {
|
||||||
auto size = actionSize();
|
auto size = actionSize();
|
||||||
|
const auto iconRect = style::rtlrect(
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
size.width(),
|
||||||
|
size.height(),
|
||||||
|
outerWidth);
|
||||||
|
if (_state == State::Invited) {
|
||||||
|
_actionRipple = nullptr;
|
||||||
|
st::groupCallMemberInvited.paint(
|
||||||
|
p,
|
||||||
|
QPoint(x, y) + st::groupCallMemberInvitedPosition,
|
||||||
|
outerWidth);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (_actionRipple) {
|
if (_actionRipple) {
|
||||||
_actionRipple->paint(
|
_actionRipple->paint(
|
||||||
p,
|
p,
|
||||||
|
@ -494,12 +548,6 @@ void Row::paintAction(
|
||||||
_actionRipple.reset();
|
_actionRipple.reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const auto iconRect = style::rtlrect(
|
|
||||||
x,
|
|
||||||
y,
|
|
||||||
size.width(),
|
|
||||||
size.height(),
|
|
||||||
outerWidth);
|
|
||||||
const auto speaking = _speakingAnimation.value(_speaking ? 1. : 0.);
|
const auto speaking = _speakingAnimation.value(_speaking ? 1. : 0.);
|
||||||
const auto active = _activeAnimation.value(
|
const auto active = _activeAnimation.value(
|
||||||
(_state == State::Active) ? 1. : 0.);
|
(_state == State::Active) ? 1. : 0.);
|
||||||
|
@ -649,6 +697,7 @@ void MembersController::subscribeToChanges(not_null<Data::GroupCall*> real) {
|
||||||
const auto user = update.was ? update.was->user : update.now->user;
|
const auto user = update.was ? update.was->user : update.now->user;
|
||||||
if (!update.now) {
|
if (!update.now) {
|
||||||
if (const auto row = findRow(user)) {
|
if (const auto row = findRow(user)) {
|
||||||
|
const auto owner = &user->owner();
|
||||||
if (user->isSelf()) {
|
if (user->isSelf()) {
|
||||||
updateRow(row, nullptr);
|
updateRow(row, nullptr);
|
||||||
} else {
|
} else {
|
||||||
|
@ -660,6 +709,30 @@ void MembersController::subscribeToChanges(not_null<Data::GroupCall*> real) {
|
||||||
updateRow(update.was, *update.now);
|
updateRow(update.was, *update.now);
|
||||||
}
|
}
|
||||||
}, _lifetime);
|
}, _lifetime);
|
||||||
|
|
||||||
|
if (_prepared) {
|
||||||
|
appendInvitedUsers();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MembersController::appendInvitedUsers() {
|
||||||
|
for (const auto user : _peer->owner().invitedToCallUsers(_realId)) {
|
||||||
|
if (auto row = createInvitedRow(user)) {
|
||||||
|
delegate()->peerListAppendRow(std::move(row));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delegate()->peerListRefreshRows();
|
||||||
|
|
||||||
|
using Invite = Data::Session::InviteToCall;
|
||||||
|
_peer->owner().invitesToCalls(
|
||||||
|
) | rpl::filter([=](const Invite &invite) {
|
||||||
|
return (invite.id == _realId);
|
||||||
|
}) | rpl::start_with_next([=](const Invite &invite) {
|
||||||
|
if (auto row = createInvitedRow(invite.user)) {
|
||||||
|
delegate()->peerListAppendRow(std::move(row));
|
||||||
|
delegate()->peerListRefreshRows();
|
||||||
|
}
|
||||||
|
}, _lifetime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MembersController::updateRow(
|
void MembersController::updateRow(
|
||||||
|
@ -796,7 +869,12 @@ void MembersController::prepare() {
|
||||||
delegate()->peerListAppendRow(std::move(row));
|
delegate()->peerListAppendRow(std::move(row));
|
||||||
delegate()->peerListRefreshRows();
|
delegate()->peerListRefreshRows();
|
||||||
}
|
}
|
||||||
|
|
||||||
loadMoreRows();
|
loadMoreRows();
|
||||||
|
if (_realId) {
|
||||||
|
appendInvitedUsers();
|
||||||
|
}
|
||||||
|
_prepared = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MembersController::prepareRows(not_null<Data::GroupCall*> real) {
|
void MembersController::prepareRows(not_null<Data::GroupCall*> real) {
|
||||||
|
@ -1056,7 +1134,9 @@ base::unique_qptr<Ui::PopupMenu> MembersController::rowContextMenu(
|
||||||
tr::lng_context_send_message(tr::now),
|
tr::lng_context_send_message(tr::now),
|
||||||
showHistory);
|
showHistory);
|
||||||
const auto canKick = [&] {
|
const auto canKick = [&] {
|
||||||
if (const auto chat = _peer->asChat()) {
|
if (static_cast<Row*>(row.get())->state() == Row::State::Invited) {
|
||||||
|
return false;
|
||||||
|
} else if (const auto chat = _peer->asChat()) {
|
||||||
return chat->amCreator()
|
return chat->amCreator()
|
||||||
|| (chat->canBanMembers() && !chat->admins.contains(user));
|
|| (chat->canBanMembers() && !chat->admins.contains(user));
|
||||||
} else if (const auto group = _peer->asMegagroup()) {
|
} else if (const auto group = _peer->asMegagroup()) {
|
||||||
|
@ -1086,6 +1166,16 @@ std::unique_ptr<Row> MembersController::createRow(
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<Row> MembersController::createInvitedRow(
|
||||||
|
not_null<UserData*> user) {
|
||||||
|
if (findRow(user)) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
auto result = std::make_unique<Row>(this, user);
|
||||||
|
updateRow(result.get(), nullptr);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
GroupMembers::GroupMembers(
|
GroupMembers::GroupMembers(
|
||||||
|
|
|
@ -841,6 +841,7 @@ void Session::registerInvitedToCallUser(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_invitedToCallUsers[callId].emplace(user);
|
_invitedToCallUsers[callId].emplace(user);
|
||||||
|
_invitesToCalls.fire({ callId, user });
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::unregisterInvitedToCallUser(
|
void Session::unregisterInvitedToCallUser(
|
||||||
|
|
|
@ -166,6 +166,14 @@ public:
|
||||||
not_null<UserData*> user);
|
not_null<UserData*> user);
|
||||||
void unregisterInvitedToCallUser(uint64 callId, not_null<UserData*> user);
|
void unregisterInvitedToCallUser(uint64 callId, not_null<UserData*> user);
|
||||||
|
|
||||||
|
struct InviteToCall {
|
||||||
|
uint64 id = 0;
|
||||||
|
not_null<UserData*> user;
|
||||||
|
};
|
||||||
|
[[nodiscard]] rpl::producer<InviteToCall> invitesToCalls() const {
|
||||||
|
return _invitesToCalls.events();
|
||||||
|
}
|
||||||
|
|
||||||
void enumerateUsers(Fn<void(not_null<UserData*>)> action) const;
|
void enumerateUsers(Fn<void(not_null<UserData*>)> action) const;
|
||||||
void enumerateGroups(Fn<void(not_null<PeerData*>)> action) const;
|
void enumerateGroups(Fn<void(not_null<PeerData*>)> action) const;
|
||||||
void enumerateChannels(Fn<void(not_null<ChannelData*>)> action) const;
|
void enumerateChannels(Fn<void(not_null<ChannelData*>)> action) const;
|
||||||
|
@ -923,6 +931,7 @@ private:
|
||||||
base::flat_set<not_null<ViewElement*>> _heavyViewParts;
|
base::flat_set<not_null<ViewElement*>> _heavyViewParts;
|
||||||
|
|
||||||
base::flat_map<uint64, not_null<GroupCall*>> _groupCalls;
|
base::flat_map<uint64, not_null<GroupCall*>> _groupCalls;
|
||||||
|
rpl::event_stream<InviteToCall> _invitesToCalls;
|
||||||
base::flat_map<uint64, base::flat_set<not_null<UserData*>>> _invitedToCallUsers;
|
base::flat_map<uint64, base::flat_set<not_null<UserData*>>> _invitedToCallUsers;
|
||||||
|
|
||||||
History *_topPromoted = nullptr;
|
History *_topPromoted = nullptr;
|
||||||
|
|
Loading…
Add table
Reference in a new issue