mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-17 22:57:11 +02:00
Correctly track mute button scheduled state.
This commit is contained in:
parent
15d17c8b0e
commit
088fda4ed8
12 changed files with 292 additions and 204 deletions
|
@ -184,6 +184,7 @@ GroupCall::GroupCall(
|
|||
, _joinAs(info.joinAs)
|
||||
, _possibleJoinAs(std::move(info.possibleJoinAs))
|
||||
, _joinHash(info.joinHash)
|
||||
, _id(inputCall.c_inputGroupCall().vid().v)
|
||||
, _scheduleDate(info.scheduleDate)
|
||||
, _lastSpokeCheckTimer([=] { checkLastSpoke(); })
|
||||
, _checkJoinedTimer([=] { checkJoined(); })
|
||||
|
@ -216,14 +217,29 @@ GroupCall::GroupCall(
|
|||
|
||||
checkGlobalShortcutAvailability();
|
||||
|
||||
const auto id = inputCall.c_inputGroupCall().vid().v;
|
||||
if (id) {
|
||||
if (const auto call = _peer->groupCall(); call && call->id() == id) {
|
||||
_scheduleDate = call->scheduleDate();
|
||||
if (!_peer->canManageGroupCall() && call->joinMuted()) {
|
||||
_muted = MuteState::ForceMuted;
|
||||
}
|
||||
if (const auto real = lookupReal()) {
|
||||
subscribeToReal(real);
|
||||
if (!_peer->canManageGroupCall() && real->joinMuted()) {
|
||||
_muted = MuteState::ForceMuted;
|
||||
}
|
||||
} else {
|
||||
_peer->session().changes().peerFlagsValue(
|
||||
_peer,
|
||||
Data::PeerUpdate::Flag::GroupCall
|
||||
) | rpl::map([=] {
|
||||
return lookupReal();
|
||||
}) | rpl::filter([](Data::GroupCall *real) {
|
||||
return real != nullptr;
|
||||
}) | rpl::map([](Data::GroupCall *real) {
|
||||
return not_null{ real };
|
||||
}) | rpl::take(
|
||||
1
|
||||
) | rpl::start_with_next([=](not_null<Data::GroupCall*> call) {
|
||||
subscribeToReal(real);
|
||||
_realChanges.fire_copy(call);
|
||||
}, _lifetime);
|
||||
}
|
||||
if (_id) {
|
||||
join(inputCall);
|
||||
} else {
|
||||
start(info.scheduleDate);
|
||||
|
@ -250,6 +266,17 @@ GroupCall::~GroupCall() {
|
|||
destroyController();
|
||||
}
|
||||
|
||||
void GroupCall::subscribeToReal(not_null<Data::GroupCall*> real) {
|
||||
real->scheduleDateValue(
|
||||
) | rpl::start_with_next([=](TimeId date) {
|
||||
const auto was = _scheduleDate;
|
||||
_scheduleDate = date;
|
||||
if (was && !date) {
|
||||
join(inputCall());
|
||||
}
|
||||
}, _lifetime);
|
||||
}
|
||||
|
||||
void GroupCall::checkGlobalShortcutAvailability() {
|
||||
auto &settings = Core::App().settings();
|
||||
if (!settings.groupCallPushToTalk()) {
|
||||
|
@ -327,6 +354,18 @@ bool GroupCall::showChooseJoinAs() const {
|
|||
&& !_possibleJoinAs.front()->isSelf());
|
||||
}
|
||||
|
||||
Data::GroupCall *GroupCall::lookupReal() const {
|
||||
const auto real = _peer->groupCall();
|
||||
return (real && real->id() == _id) ? real : nullptr;
|
||||
}
|
||||
|
||||
rpl::producer<not_null<Data::GroupCall*>> GroupCall::real() const {
|
||||
if (const auto real = lookupReal()) {
|
||||
return rpl::single(not_null{ real });
|
||||
}
|
||||
return _realChanges.events();
|
||||
}
|
||||
|
||||
void GroupCall::start(TimeId scheduleDate) {
|
||||
using Flag = MTPphone_CreateGroupCall::Flag;
|
||||
_createRequestId = _api.request(MTPphone_CreateGroupCall(
|
||||
|
@ -699,6 +738,29 @@ void GroupCall::finish(FinishType type) {
|
|||
})).send();
|
||||
}
|
||||
|
||||
void GroupCall::startScheduledNow() {
|
||||
if (!lookupReal()) {
|
||||
return;
|
||||
}
|
||||
_api.request(MTPphone_StartScheduledGroupCall(
|
||||
inputCall()
|
||||
)).done([=](const MTPUpdates &result) {
|
||||
_peer->session().api().applyUpdates(result);
|
||||
}).send();
|
||||
}
|
||||
|
||||
void GroupCall::toggleScheduleStartSubscribed(bool subscribed) {
|
||||
if (!lookupReal()) {
|
||||
return;
|
||||
}
|
||||
_api.request(MTPphone_ToggleGroupCallStartSubscription(
|
||||
inputCall(),
|
||||
MTP_bool(subscribed)
|
||||
)).done([=](const MTPUpdates &result) {
|
||||
_peer->session().api().applyUpdates(result);
|
||||
}).send();
|
||||
}
|
||||
|
||||
void GroupCall::setMuted(MuteState mute) {
|
||||
const auto set = [=] {
|
||||
const auto wasMuted = (muted() == MuteState::Muted)
|
||||
|
@ -744,6 +806,8 @@ void GroupCall::handlePossibleCreateOrJoinResponse(
|
|||
const MTPDgroupCall &data) {
|
||||
if (const auto date = data.vschedule_date()) {
|
||||
_scheduleDate = date->v;
|
||||
} else {
|
||||
_scheduleDate = 0;
|
||||
}
|
||||
if (_acceptFields) {
|
||||
if (!_instance && !_id) {
|
||||
|
@ -841,10 +905,8 @@ void GroupCall::handlePossibleDiscarded(const MTPDgroupCallDiscarded &data) {
|
|||
}
|
||||
|
||||
void GroupCall::addParticipantsToInstance() {
|
||||
const auto real = _peer->groupCall();
|
||||
if (!real
|
||||
|| (real->id() != _id)
|
||||
|| (_instanceMode == InstanceMode::None)) {
|
||||
const auto real = lookupReal();
|
||||
if (!real || (_instanceMode == InstanceMode::None)) {
|
||||
return;
|
||||
}
|
||||
for (const auto &participant : real->participants()) {
|
||||
|
@ -866,7 +928,7 @@ void GroupCall::addPreparedParticipants() {
|
|||
if (!_preparedParticipants.empty()) {
|
||||
_instance->addParticipants(base::take(_preparedParticipants));
|
||||
}
|
||||
if (const auto real = _peer->groupCall(); real && real->id() == _id) {
|
||||
if (const auto real = lookupReal()) {
|
||||
if (!_unresolvedSsrcs.empty()) {
|
||||
real->resolveParticipants(base::take(_unresolvedSsrcs));
|
||||
}
|
||||
|
@ -989,8 +1051,8 @@ void GroupCall::handleUpdate(const MTPDupdateGroupCallParticipants &data) {
|
|||
}
|
||||
|
||||
void GroupCall::changeTitle(const QString &title) {
|
||||
const auto real = _peer->groupCall();
|
||||
if (!real || real->id() != _id || real->title() == title) {
|
||||
const auto real = lookupReal();
|
||||
if (!real || real->title() == title) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1005,8 +1067,8 @@ void GroupCall::changeTitle(const QString &title) {
|
|||
}
|
||||
|
||||
void GroupCall::toggleRecording(bool enabled, const QString &title) {
|
||||
const auto real = _peer->groupCall();
|
||||
if (!real || real->id() != _id) {
|
||||
const auto real = lookupReal();
|
||||
if (!real) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1185,10 +1247,8 @@ void GroupCall::broadcastPartCancel(not_null<LoadPartTask*> task) {
|
|||
|
||||
void GroupCall::requestParticipantsInformation(
|
||||
const std::vector<uint32_t> &ssrcs) {
|
||||
const auto real = _peer->groupCall();
|
||||
if (!real
|
||||
|| (real->id() != _id)
|
||||
|| (_instanceMode == InstanceMode::None)) {
|
||||
const auto real = lookupReal();
|
||||
if (!real || (_instanceMode == InstanceMode::None)) {
|
||||
for (const auto ssrc : ssrcs) {
|
||||
_unresolvedSsrcs.emplace(ssrc);
|
||||
}
|
||||
|
@ -1222,8 +1282,8 @@ void GroupCall::updateInstanceMuteState() {
|
|||
}
|
||||
|
||||
void GroupCall::updateInstanceVolumes() {
|
||||
const auto real = _peer->groupCall();
|
||||
if (!real || real->id() != _id) {
|
||||
const auto real = lookupReal();
|
||||
if (!real) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1299,8 +1359,8 @@ void GroupCall::audioLevelsUpdated(const tgcalls::GroupLevelsUpdate &data) {
|
|||
}
|
||||
|
||||
void GroupCall::checkLastSpoke() {
|
||||
const auto real = _peer->groupCall();
|
||||
if (!real || real->id() != _id) {
|
||||
const auto real = lookupReal();
|
||||
if (!real) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1511,8 +1571,8 @@ void GroupCall::editParticipant(
|
|||
|
||||
std::variant<int, not_null<UserData*>> GroupCall::inviteUsers(
|
||||
const std::vector<not_null<UserData*>> &users) {
|
||||
const auto real = _peer->groupCall();
|
||||
if (!real || real->id() != _id) {
|
||||
const auto real = lookupReal();
|
||||
if (!real) {
|
||||
return 0;
|
||||
}
|
||||
const auto owner = &_peer->owner();
|
||||
|
|
|
@ -34,6 +34,7 @@ class MediaDevices;
|
|||
namespace Data {
|
||||
struct LastSpokeTimes;
|
||||
struct GroupCallParticipant;
|
||||
class GroupCall;
|
||||
} // namespace Data
|
||||
|
||||
namespace Calls {
|
||||
|
@ -113,6 +114,9 @@ public:
|
|||
return _scheduleDate;
|
||||
}
|
||||
|
||||
[[nodiscard]] Data::GroupCall *lookupReal() const;
|
||||
[[nodiscard]] rpl::producer<not_null<Data::GroupCall*>> real() const;
|
||||
|
||||
void start(TimeId scheduleDate);
|
||||
void hangup();
|
||||
void discard();
|
||||
|
@ -126,6 +130,8 @@ public:
|
|||
[[nodiscard]] bool recordingStoppedByMe() const {
|
||||
return _recordingStoppedByMe;
|
||||
}
|
||||
void startScheduledNow();
|
||||
void toggleScheduleStartSubscribed(bool subscribed);
|
||||
|
||||
void setMuted(MuteState mute);
|
||||
void setMutedAndUpdate(MuteState mute);
|
||||
|
@ -249,6 +255,7 @@ private:
|
|||
void applyMeInCallLocally();
|
||||
void rejoin();
|
||||
void rejoin(not_null<PeerData*> as);
|
||||
void subscribeToReal(not_null<Data::GroupCall*> real);
|
||||
|
||||
void audioLevelsUpdated(const tgcalls::GroupLevelsUpdate &data);
|
||||
void setInstanceConnected(tgcalls::GroupNetworkState networkState);
|
||||
|
@ -288,6 +295,7 @@ private:
|
|||
rpl::event_stream<PeerData*> _peerStream;
|
||||
not_null<History*> _history; // Can change in legacy group migration.
|
||||
MTP::Sender _api;
|
||||
rpl::event_stream<not_null<Data::GroupCall*>> _realChanges;
|
||||
rpl::variable<State> _state = State::Creating;
|
||||
rpl::variable<InstanceState> _instanceState
|
||||
= InstanceState::Disconnected;
|
||||
|
|
|
@ -317,7 +317,7 @@ private:
|
|||
not_null<PeerData*> participantPeer,
|
||||
bool participantIsCallAdmin,
|
||||
not_null<Row*> row);
|
||||
void setupListChangeViewers(not_null<GroupCall*> call);
|
||||
void setupListChangeViewers();
|
||||
void subscribeToChanges(not_null<Data::GroupCall*> real);
|
||||
void updateRow(
|
||||
const std::optional<Data::GroupCall::Participant> &was,
|
||||
|
@ -335,16 +335,11 @@ private:
|
|||
uint64 raiseHandRating) const;
|
||||
Row *findRow(not_null<PeerData*> participantPeer) const;
|
||||
|
||||
[[nodiscard]] Data::GroupCall *resolvedRealCall() const;
|
||||
void appendInvitedUsers();
|
||||
void scheduleRaisedHandStatusRemove();
|
||||
|
||||
const base::weak_ptr<GroupCall> _call;
|
||||
const not_null<GroupCall*> _call;
|
||||
not_null<PeerData*> _peer;
|
||||
|
||||
// Use only resolvedRealCall() method, not this value directly.
|
||||
Data::GroupCall *_realCallRawValue = nullptr;
|
||||
uint64 _realId = 0;
|
||||
bool _prepared = false;
|
||||
|
||||
rpl::event_stream<MuteRequest> _toggleMuteRequests;
|
||||
|
@ -909,7 +904,7 @@ MembersController::MembersController(
|
|||
, _raisedHandStatusRemoveTimer([=] { scheduleRaisedHandStatusRemove(); })
|
||||
, _inactiveCrossLine(st::groupCallMemberInactiveCrossLine)
|
||||
, _coloredCrossLine(st::groupCallMemberColoredCrossLine) {
|
||||
setupListChangeViewers(call);
|
||||
setupListChangeViewers();
|
||||
|
||||
style::PaletteChanged(
|
||||
) | rpl::start_with_next([=] {
|
||||
|
@ -964,32 +959,20 @@ MembersController::~MembersController() {
|
|||
base::take(_menu);
|
||||
}
|
||||
|
||||
void MembersController::setupListChangeViewers(not_null<GroupCall*> call) {
|
||||
const auto peer = call->peer();
|
||||
peer->session().changes().peerFlagsValue(
|
||||
peer,
|
||||
Data::PeerUpdate::Flag::GroupCall
|
||||
) | rpl::map([=] {
|
||||
return peer->groupCall();
|
||||
}) | rpl::filter([=](Data::GroupCall *real) {
|
||||
const auto call = _call.get();
|
||||
return call && real && (real->id() == call->id());
|
||||
}) | rpl::take(
|
||||
1
|
||||
void MembersController::setupListChangeViewers() {
|
||||
_call->real(
|
||||
) | rpl::start_with_next([=](not_null<Data::GroupCall*> real) {
|
||||
subscribeToChanges(real);
|
||||
}, _lifetime);
|
||||
|
||||
call->stateValue(
|
||||
_call->stateValue(
|
||||
) | rpl::start_with_next([=] {
|
||||
const auto call = _call.get();
|
||||
const auto real = peer->groupCall();
|
||||
if (call && real && (real->id() == call->id())) {
|
||||
if (const auto real = _call->lookupReal()) {
|
||||
//updateRow(channel->session().user());
|
||||
}
|
||||
}, _lifetime);
|
||||
|
||||
call->levelUpdates(
|
||||
_call->levelUpdates(
|
||||
) | rpl::start_with_next([=](const LevelUpdate &update) {
|
||||
const auto i = _soundingRowBySsrc.find(update.ssrc);
|
||||
if (i != end(_soundingRowBySsrc)) {
|
||||
|
@ -997,7 +980,7 @@ void MembersController::setupListChangeViewers(not_null<GroupCall*> call) {
|
|||
}
|
||||
}, _lifetime);
|
||||
|
||||
call->rejoinEvents(
|
||||
_call->rejoinEvents(
|
||||
) | rpl::start_with_next([=](const Group::RejoinEvent &event) {
|
||||
const auto guard = gsl::finally([&] {
|
||||
delegate()->peerListRefreshRows();
|
||||
|
@ -1014,9 +997,6 @@ void MembersController::setupListChangeViewers(not_null<GroupCall*> call) {
|
|||
}
|
||||
|
||||
void MembersController::subscribeToChanges(not_null<Data::GroupCall*> real) {
|
||||
_realCallRawValue = real;
|
||||
_realId = real->id();
|
||||
|
||||
_fullCount = real->fullCountValue();
|
||||
|
||||
real->participantsSliceAdded(
|
||||
|
@ -1053,17 +1033,19 @@ void MembersController::subscribeToChanges(not_null<Data::GroupCall*> real) {
|
|||
}
|
||||
|
||||
void MembersController::appendInvitedUsers() {
|
||||
for (const auto user : _peer->owner().invitedToCallUsers(_realId)) {
|
||||
if (auto row = createInvitedRow(user)) {
|
||||
delegate()->peerListAppendRow(std::move(row));
|
||||
if (const auto id = _call->id()) {
|
||||
for (const auto user : _peer->owner().invitedToCallUsers(id)) {
|
||||
if (auto row = createInvitedRow(user)) {
|
||||
delegate()->peerListAppendRow(std::move(row));
|
||||
}
|
||||
}
|
||||
delegate()->peerListRefreshRows();
|
||||
}
|
||||
delegate()->peerListRefreshRows();
|
||||
|
||||
using Invite = Data::Session::InviteToCall;
|
||||
_peer->owner().invitesToCalls(
|
||||
) | rpl::filter([=](const Invite &invite) {
|
||||
return (invite.id == _realId);
|
||||
return (invite.id == _call->id());
|
||||
}) | rpl::start_with_next([=](const Invite &invite) {
|
||||
if (auto row = createInvitedRow(invite.user)) {
|
||||
delegate()->peerListAppendRow(std::move(row));
|
||||
|
@ -1120,7 +1102,7 @@ void MembersController::updateRow(
|
|||
if (checkPosition) {
|
||||
checkRowPosition(checkPosition);
|
||||
} else if (addedToBottom) {
|
||||
const auto real = resolvedRealCall();
|
||||
const auto real = _call->lookupReal();
|
||||
if (real && real->joinedToTop()) {
|
||||
const auto proj = [&](const PeerListRow &other) {
|
||||
const auto &real = static_cast<const Row&>(other);
|
||||
|
@ -1314,14 +1296,6 @@ Row *MembersController::findRow(not_null<PeerData*> participantPeer) const {
|
|||
delegate()->peerListFindRow(participantPeer->id));
|
||||
}
|
||||
|
||||
Data::GroupCall *MembersController::resolvedRealCall() const {
|
||||
return (_realCallRawValue
|
||||
&& (_peer->groupCall() == _realCallRawValue)
|
||||
&& (_realCallRawValue->id() == _realId))
|
||||
? _realCallRawValue
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
Main::Session &MembersController::session() const {
|
||||
return _call->peer()->session();
|
||||
}
|
||||
|
@ -1332,9 +1306,7 @@ void MembersController::prepare() {
|
|||
setDescriptionText(tr::lng_contacts_loading(tr::now));
|
||||
setSearchNoResultsText(tr::lng_blocked_list_not_found(tr::now));
|
||||
|
||||
const auto call = _call.get();
|
||||
if (const auto real = _peer->groupCall()
|
||||
; real && call && real->id() == call->id()) {
|
||||
if (const auto real = _call->lookupReal()) {
|
||||
prepareRows(real);
|
||||
} else if (auto row = createRowForMe()) {
|
||||
delegate()->peerListAppendRow(std::move(row));
|
||||
|
@ -1342,15 +1314,12 @@ void MembersController::prepare() {
|
|||
}
|
||||
|
||||
loadMoreRows();
|
||||
if (_realId) {
|
||||
appendInvitedUsers();
|
||||
}
|
||||
appendInvitedUsers();
|
||||
_prepared = true;
|
||||
}
|
||||
|
||||
bool MembersController::isMe(not_null<PeerData*> participantPeer) const {
|
||||
const auto call = _call.get();
|
||||
return call && (call->joinAs() == participantPeer);
|
||||
return (_call->joinAs() == participantPeer);
|
||||
}
|
||||
|
||||
void MembersController::prepareRows(not_null<Data::GroupCall*> real) {
|
||||
|
@ -1379,19 +1348,17 @@ void MembersController::prepareRows(not_null<Data::GroupCall*> real) {
|
|||
}
|
||||
}
|
||||
if (!foundMe) {
|
||||
if (const auto call = _call.get()) {
|
||||
const auto me = call->joinAs();
|
||||
const auto i = ranges::find(
|
||||
participants,
|
||||
me,
|
||||
&Data::GroupCall::Participant::peer);
|
||||
auto row = (i != end(participants))
|
||||
? createRow(*i)
|
||||
: createRowForMe();
|
||||
if (row) {
|
||||
changed = true;
|
||||
delegate()->peerListAppendRow(std::move(row));
|
||||
}
|
||||
const auto me = _call->joinAs();
|
||||
const auto i = ranges::find(
|
||||
participants,
|
||||
me,
|
||||
&Data::GroupCall::Participant::peer);
|
||||
auto row = (i != end(participants))
|
||||
? createRow(*i)
|
||||
: createRowForMe();
|
||||
if (row) {
|
||||
changed = true;
|
||||
delegate()->peerListAppendRow(std::move(row));
|
||||
}
|
||||
}
|
||||
for (const auto &participant : participants) {
|
||||
|
@ -1406,7 +1373,7 @@ void MembersController::prepareRows(not_null<Data::GroupCall*> real) {
|
|||
}
|
||||
|
||||
void MembersController::loadMoreRows() {
|
||||
if (const auto real = _peer->groupCall()) {
|
||||
if (const auto real = _call->lookupReal()) {
|
||||
real->requestParticipants();
|
||||
}
|
||||
}
|
||||
|
@ -1634,12 +1601,10 @@ base::unique_qptr<Ui::PopupMenu> MembersController::createRowContextMenu(
|
|||
}
|
||||
|
||||
if (isMe(participantPeer)) {
|
||||
if (const auto strong = _call.get()
|
||||
; strong && strong->muted() == MuteState::RaisedHand) {
|
||||
if (_call->muted() == MuteState::RaisedHand) {
|
||||
const auto removeHand = [=] {
|
||||
if (const auto strong = _call.get()
|
||||
; strong && strong->muted() == MuteState::RaisedHand) {
|
||||
strong->setMutedAndUpdate(MuteState::ForceMuted);
|
||||
if (_call->muted() == MuteState::RaisedHand) {
|
||||
_call->setMutedAndUpdate(MuteState::ForceMuted);
|
||||
}
|
||||
};
|
||||
result->addAction(
|
||||
|
@ -1728,14 +1693,12 @@ void MembersController::addMuteActionsToContextMenu(
|
|||
|
||||
auto mutesFromVolume = rpl::never<bool>() | rpl::type_erased();
|
||||
|
||||
const auto call = _call.get();
|
||||
if (!isMuted || (call && call->joinAs() == participantPeer)) {
|
||||
auto otherParticipantStateValue = call
|
||||
? call->otherParticipantStateValue(
|
||||
) | rpl::filter([=](const Group::ParticipantState &data) {
|
||||
return data.peer == participantPeer;
|
||||
})
|
||||
: rpl::never<Group::ParticipantState>() | rpl::type_erased();
|
||||
if (!isMuted || _call->joinAs() == participantPeer) {
|
||||
auto otherParticipantStateValue
|
||||
= _call->otherParticipantStateValue(
|
||||
) | rpl::filter([=](const Group::ParticipantState &data) {
|
||||
return data.peer == participantPeer;
|
||||
});
|
||||
|
||||
auto volumeItem = base::make_unique_q<MenuVolumeItem>(
|
||||
menu->menu(),
|
||||
|
@ -1814,11 +1777,7 @@ void MembersController::addMuteActionsToContextMenu(
|
|||
}
|
||||
|
||||
std::unique_ptr<Row> MembersController::createRowForMe() {
|
||||
const auto call = _call.get();
|
||||
if (!call) {
|
||||
return nullptr;
|
||||
}
|
||||
auto result = std::make_unique<Row>(this, call->joinAs());
|
||||
auto result = std::make_unique<Row>(this, _call->joinAs());
|
||||
updateRow(result.get(), nullptr);
|
||||
return result;
|
||||
}
|
||||
|
@ -1877,12 +1836,8 @@ auto Members::kickParticipantRequests() const
|
|||
int Members::desiredHeight() const {
|
||||
const auto top = _addMember ? _addMember->height() : 0;
|
||||
auto count = [&] {
|
||||
if (const auto call = _call.get()) {
|
||||
if (const auto real = call->peer()->groupCall()) {
|
||||
if (call->id() == real->id()) {
|
||||
return real->fullCount();
|
||||
}
|
||||
}
|
||||
if (const auto real = _call->lookupReal()) {
|
||||
return real->fullCount();
|
||||
}
|
||||
return 0;
|
||||
}();
|
||||
|
@ -1911,16 +1866,7 @@ void Members::setupAddMember(not_null<GroupCall*> call) {
|
|||
if (const auto channel = peer->asBroadcast()) {
|
||||
_canAddMembers = rpl::single(
|
||||
false
|
||||
) | rpl::then(peer->session().changes().peerFlagsValue(
|
||||
peer,
|
||||
Data::PeerUpdate::Flag::GroupCall
|
||||
) | rpl::map([=] {
|
||||
return peer->groupCall();
|
||||
}) | rpl::filter([=](Data::GroupCall *real) {
|
||||
const auto call = _call.get();
|
||||
return call && real && (real->id() == call->id());
|
||||
}) | rpl::take(
|
||||
1
|
||||
) | rpl::then(_call->real(
|
||||
) | rpl::map([=] {
|
||||
return Data::PeerFlagValue(
|
||||
channel,
|
||||
|
|
|
@ -75,7 +75,7 @@ private:
|
|||
|
||||
void updateControlsGeometry();
|
||||
|
||||
const base::weak_ptr<GroupCall> _call;
|
||||
const not_null<GroupCall*> _call;
|
||||
object_ptr<Ui::ScrollArea> _scroll;
|
||||
std::unique_ptr<PeerListController> _listController;
|
||||
object_ptr<Ui::SettingsButton> _addMember = { nullptr };
|
||||
|
|
|
@ -34,6 +34,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "data/data_group_call.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_changes.h"
|
||||
#include "data/data_peer_values.h"
|
||||
#include "main/main_session.h"
|
||||
#include "base/event_filter.h"
|
||||
#include "boxes/peers/edit_participants_box.h"
|
||||
|
@ -259,14 +260,17 @@ Panel::Panel(not_null<GroupCall*> call)
|
|||
_window->body(),
|
||||
st::groupCallTitle))
|
||||
#endif // !Q_OS_MAC
|
||||
, _scheduleDate(call->scheduleDate())
|
||||
, _settings(widget(), st::groupCallSettings)
|
||||
, _mute(std::make_unique<Ui::CallMuteButton>(
|
||||
widget(),
|
||||
Core::App().appDeactivatedValue(),
|
||||
Ui::CallMuteButtonState{
|
||||
.text = tr::lng_group_call_connecting(tr::now),
|
||||
.type = Ui::CallMuteButtonType::Connecting,
|
||||
.text = (_call->scheduleDate()
|
||||
? "Start Now" // #TODO voice chats
|
||||
: tr::lng_group_call_connecting(tr::now)),
|
||||
.type = (_call->scheduleDate()
|
||||
? Ui::CallMuteButtonType::ScheduledCanStart
|
||||
: Ui::CallMuteButtonType::Connecting),
|
||||
}))
|
||||
, _hangup(widget(), st::groupCallHangup) {
|
||||
_layerBg->setStyleOverrides(&st::groupCallBox, &st::groupCallLayerBox);
|
||||
|
@ -277,7 +281,7 @@ Panel::Panel(not_null<GroupCall*> call)
|
|||
_peer,
|
||||
_window->lifetime(),
|
||||
[=](not_null<ChannelData*> channel) { migrate(channel); });
|
||||
setupRealCallViewers(call);
|
||||
setupRealCallViewers();
|
||||
|
||||
initWindow();
|
||||
initWidget();
|
||||
|
@ -295,17 +299,8 @@ Panel::~Panel() {
|
|||
}
|
||||
}
|
||||
|
||||
void Panel::setupRealCallViewers(not_null<GroupCall*> call) {
|
||||
const auto peer = call->peer();
|
||||
peer->session().changes().peerFlagsValue(
|
||||
peer,
|
||||
Data::PeerUpdate::Flag::GroupCall
|
||||
) | rpl::map([=] {
|
||||
return peer->groupCall();
|
||||
}) | rpl::filter([=](Data::GroupCall *real) {
|
||||
return real && (real->id() == _call->id());
|
||||
}) | rpl::take(
|
||||
1
|
||||
void Panel::setupRealCallViewers() {
|
||||
_call->real(
|
||||
) | rpl::start_with_next([=](not_null<Data::GroupCall*> real) {
|
||||
subscribeToChanges(real);
|
||||
}, _window->lifetime());
|
||||
|
@ -430,6 +425,15 @@ void Panel::initControls() {
|
|||
) | rpl::filter([=](Qt::MouseButton button) {
|
||||
return (button == Qt::LeftButton);
|
||||
}) | rpl::start_with_next([=] {
|
||||
if (_call->scheduleDate()) {
|
||||
if (_peer->canManageGroupCall()) {
|
||||
_call->startScheduledNow();
|
||||
} else if (const auto real = _call->lookupReal()) {
|
||||
_call->toggleScheduleStartSubscribed(
|
||||
!real->scheduleStartSubscribed());
|
||||
}
|
||||
return;
|
||||
}
|
||||
const auto oldState = _call->muted();
|
||||
const auto newState = (oldState == MuteState::ForceMuted)
|
||||
? MuteState::RaisedHand
|
||||
|
@ -449,10 +453,6 @@ void Panel::initControls() {
|
|||
_settings->setText(tr::lng_group_call_settings());
|
||||
_hangup->setText(tr::lng_group_call_leave());
|
||||
|
||||
if (!_call->scheduleDate()) {
|
||||
setupMembers();
|
||||
}
|
||||
|
||||
_call->stateValue(
|
||||
) | rpl::filter([](State state) {
|
||||
return (state == State::HangingUp)
|
||||
|
@ -470,18 +470,38 @@ void Panel::initControls() {
|
|||
_mute->setLevel(update.value);
|
||||
}, _callLifetime);
|
||||
|
||||
_call->real(
|
||||
) | rpl::start_with_next([=](not_null<Data::GroupCall*> real) {
|
||||
setupRealMuteButtonState(real);
|
||||
}, _callLifetime);
|
||||
}
|
||||
|
||||
void Panel::setupRealMuteButtonState(not_null<Data::GroupCall*> real) {
|
||||
using namespace rpl::mappers;
|
||||
rpl::combine(
|
||||
_call->mutedValue() | MapPushToTalkToActive(),
|
||||
_call->instanceStateValue()
|
||||
_call->instanceStateValue(),
|
||||
real->scheduleDateValue(),
|
||||
real->scheduleStartSubscribedValue(),
|
||||
Data::CanManageGroupCallValue(_peer)
|
||||
) | rpl::distinct_until_changed(
|
||||
) | rpl::filter(
|
||||
_2 != GroupCall::InstanceState::TransitionToRtc
|
||||
) | rpl::start_with_next([=](
|
||||
MuteState mute,
|
||||
GroupCall::InstanceState state) {
|
||||
GroupCall::InstanceState state,
|
||||
TimeId scheduleDate,
|
||||
bool scheduleStartSubscribed,
|
||||
bool canManage) {
|
||||
using Type = Ui::CallMuteButtonType;
|
||||
_mute->setState(Ui::CallMuteButtonState{
|
||||
.text = (state == GroupCall::InstanceState::Disconnected
|
||||
.text = (scheduleDate
|
||||
? (canManage
|
||||
? "Start Now" // #TODO voice chats
|
||||
: scheduleStartSubscribed
|
||||
? "Cancel Reminder"
|
||||
: "Set Reminder")
|
||||
: state == GroupCall::InstanceState::Disconnected
|
||||
? tr::lng_group_call_connecting(tr::now)
|
||||
: mute == MuteState::ForceMuted
|
||||
? tr::lng_group_call_force_muted(tr::now)
|
||||
|
@ -490,7 +510,9 @@ void Panel::initControls() {
|
|||
: mute == MuteState::Muted
|
||||
? tr::lng_group_call_unmute(tr::now)
|
||||
: tr::lng_group_call_you_are_live(tr::now)),
|
||||
.subtext = (state == GroupCall::InstanceState::Disconnected
|
||||
.subtext = (scheduleDate
|
||||
? QString()
|
||||
: state == GroupCall::InstanceState::Disconnected
|
||||
? QString()
|
||||
: mute == MuteState::ForceMuted
|
||||
? tr::lng_group_call_raise_hand_tip(tr::now)
|
||||
|
@ -499,15 +521,21 @@ void Panel::initControls() {
|
|||
: mute == MuteState::Muted
|
||||
? tr::lng_group_call_unmute_sub(tr::now)
|
||||
: QString()),
|
||||
.type = (state == GroupCall::InstanceState::Disconnected
|
||||
? Ui::CallMuteButtonType::Connecting
|
||||
.type = (scheduleDate
|
||||
? (canManage
|
||||
? Type::ScheduledCanStart
|
||||
: scheduleStartSubscribed
|
||||
? Type::ScheduledNotify
|
||||
: Type::ScheduledSilent)
|
||||
: state == GroupCall::InstanceState::Disconnected
|
||||
? Type::Connecting
|
||||
: mute == MuteState::ForceMuted
|
||||
? Ui::CallMuteButtonType::ForceMuted
|
||||
? Type::ForceMuted
|
||||
: mute == MuteState::RaisedHand
|
||||
? Ui::CallMuteButtonType::RaisedHand
|
||||
? Type::RaisedHand
|
||||
: mute == MuteState::Muted
|
||||
? Ui::CallMuteButtonType::Muted
|
||||
: Ui::CallMuteButtonType::Active),
|
||||
? Type::Muted
|
||||
: Type::Active),
|
||||
});
|
||||
}, _callLifetime);
|
||||
}
|
||||
|
@ -590,8 +618,7 @@ void Panel::setupJoinAsChangedToasts() {
|
|||
void Panel::setupTitleChangedToasts() {
|
||||
_call->titleChanged(
|
||||
) | rpl::filter([=] {
|
||||
const auto real = _peer->groupCall();
|
||||
return real && (real->id() == _call->id());
|
||||
return (_call->lookupReal() != nullptr);
|
||||
}) | rpl::map([=] {
|
||||
return _peer->groupCall()->title().isEmpty()
|
||||
? _peer->name
|
||||
|
@ -617,10 +644,8 @@ void Panel::setupAllowedToSpeakToasts() {
|
|||
.text = { tr::lng_group_call_can_speak_here(tr::now) },
|
||||
});
|
||||
} else {
|
||||
const auto real = _peer->groupCall();
|
||||
const auto name = (real
|
||||
&& (real->id() == _call->id())
|
||||
&& !real->title().isEmpty())
|
||||
const auto real = _call->lookupReal();
|
||||
const auto name = (real && !real->title().isEmpty())
|
||||
? real->title()
|
||||
: _peer->name;
|
||||
Ui::ShowMultilineToast({
|
||||
|
@ -635,18 +660,6 @@ void Panel::setupAllowedToSpeakToasts() {
|
|||
}
|
||||
|
||||
void Panel::subscribeToChanges(not_null<Data::GroupCall*> real) {
|
||||
if (!_members) {
|
||||
real->scheduleDateValue(
|
||||
) | rpl::filter([=](TimeId scheduleDate) {
|
||||
return !scheduleDate;
|
||||
}) | rpl::take(1) | rpl::start_with_next([=] {
|
||||
setupMembers();
|
||||
}, _callLifetime);
|
||||
}
|
||||
|
||||
_titleText = real->titleValue();
|
||||
_scheduleDate = real->scheduleDateValue();
|
||||
|
||||
const auto validateRecordingMark = [=](bool recording) {
|
||||
if (!recording && _recordingMark) {
|
||||
_recordingMark.destroy();
|
||||
|
@ -823,8 +836,8 @@ void Panel::showMainMenu() {
|
|||
}
|
||||
|
||||
void Panel::addMembers() {
|
||||
const auto real = _peer->groupCall();
|
||||
if (!real || real->id() != _call->id()) {
|
||||
const auto real = _call->lookupReal();
|
||||
if (!real) {
|
||||
return;
|
||||
}
|
||||
auto alreadyIn = _peer->owner().invitedToCallUsers(real->id());
|
||||
|
@ -1135,7 +1148,12 @@ void Panel::refreshTitle() {
|
|||
if (!_title) {
|
||||
auto text = rpl::combine(
|
||||
Info::Profile::NameValue(_peer),
|
||||
_titleText.value()
|
||||
rpl::single(
|
||||
QString()
|
||||
) | rpl::then(_call->real(
|
||||
) | rpl::map([=](not_null<Data::GroupCall*> real) {
|
||||
return real->titleValue();
|
||||
}) | rpl::flatten_latest())
|
||||
) | rpl::map([=](
|
||||
const TextWithEntities &name,
|
||||
const QString &title) {
|
||||
|
@ -1154,15 +1172,24 @@ void Panel::refreshTitle() {
|
|||
if (!_subtitle) {
|
||||
_subtitle.create(
|
||||
widget(),
|
||||
_scheduleDate.value(
|
||||
rpl::single(
|
||||
_call->scheduleDate()
|
||||
) | rpl::then(
|
||||
_call->real(
|
||||
) | rpl::map([=](not_null<Data::GroupCall*> real) {
|
||||
return real->scheduleDateValue();
|
||||
}) | rpl::flatten_latest()
|
||||
) | rpl::map([=](TimeId scheduleDate) {
|
||||
return scheduleDate
|
||||
? tr::lng_group_call_scheduled_status()
|
||||
: tr::lng_group_call_members(
|
||||
lt_count_decimal,
|
||||
_members->fullCountValue() | rpl::map([](int value) {
|
||||
return (value > 0) ? float64(value) : 1.;
|
||||
}));
|
||||
if (scheduleDate) {
|
||||
return tr::lng_group_call_scheduled_status();
|
||||
} else if (!_members) {
|
||||
setupMembers();
|
||||
}
|
||||
return tr::lng_group_call_members(
|
||||
lt_count_decimal,
|
||||
_members->fullCountValue() | rpl::map([](int value) {
|
||||
return (value > 0) ? float64(value) : 1.;
|
||||
}));
|
||||
}) | rpl::flatten_latest(),
|
||||
st::groupCallSubtitleLabel);
|
||||
_subtitle->show();
|
||||
|
|
|
@ -79,6 +79,7 @@ private:
|
|||
void setupJoinAsChangedToasts();
|
||||
void setupTitleChangedToasts();
|
||||
void setupAllowedToSpeakToasts();
|
||||
void setupRealMuteButtonState(not_null<Data::GroupCall*> real);
|
||||
|
||||
bool handleClose();
|
||||
|
||||
|
@ -96,7 +97,7 @@ private:
|
|||
[[nodiscard]] QRect computeTitleRect() const;
|
||||
void refreshTitle();
|
||||
void refreshTitleGeometry();
|
||||
void setupRealCallViewers(not_null<GroupCall*> call);
|
||||
void setupRealCallViewers();
|
||||
void subscribeToChanges(not_null<Data::GroupCall*> real);
|
||||
|
||||
void migrate(not_null<ChannelData*> channel);
|
||||
|
@ -121,8 +122,6 @@ private:
|
|||
object_ptr<Ui::DropdownMenu> _menu = { nullptr };
|
||||
object_ptr<Ui::AbstractButton> _joinAsToggle = { nullptr };
|
||||
object_ptr<Members> _members = { nullptr };
|
||||
rpl::variable<QString> _titleText;
|
||||
rpl::variable<TimeId> _scheduleDate;
|
||||
ChooseJoinAsProcess _joinAsProcess;
|
||||
|
||||
object_ptr<Ui::CallButton> _settings;
|
||||
|
|
|
@ -330,6 +330,7 @@ void GroupCall::applyCallFields(const MTPDgroupCall &data) {
|
|||
_title = qs(data.vtitle().value_or_empty());
|
||||
_recordStartDate = data.vrecord_start_date().value_or_empty();
|
||||
_scheduleDate = data.vschedule_date().value_or_empty();
|
||||
_scheduleStartSubscribed = data.is_schedule_start_subscribed();
|
||||
_allParticipantsLoaded
|
||||
= (_serverParticipantsCount == _participants.size());
|
||||
}
|
||||
|
|
|
@ -72,6 +72,12 @@ public:
|
|||
[[nodiscard]] rpl::producer<TimeId> scheduleDateChanges() const {
|
||||
return _scheduleDate.changes();
|
||||
}
|
||||
[[nodiscard]] bool scheduleStartSubscribed() const {
|
||||
return _scheduleStartSubscribed.current();
|
||||
}
|
||||
[[nodiscard]] rpl::producer<bool> scheduleStartSubscribedValue() const {
|
||||
return _scheduleStartSubscribed.value();
|
||||
}
|
||||
|
||||
void setPeer(not_null<PeerData*> peer);
|
||||
|
||||
|
@ -173,6 +179,7 @@ private:
|
|||
rpl::variable<int> _fullCount = 0;
|
||||
rpl::variable<TimeId> _recordStartDate = 0;
|
||||
rpl::variable<TimeId> _scheduleDate = 0;
|
||||
rpl::variable<bool> _scheduleStartSubscribed = false;
|
||||
|
||||
base::flat_map<uint32, LastSpokeTimes> _unknownSpokenSsrcs;
|
||||
base::flat_map<PeerId, LastSpokeTimes> _unknownSpokenPeerIds;
|
||||
|
|
|
@ -320,6 +320,20 @@ rpl::producer<bool> CanPinMessagesValue(not_null<PeerData*> peer) {
|
|||
Unexpected("Peer type in CanPinMessagesValue.");
|
||||
}
|
||||
|
||||
rpl::producer<bool> CanManageGroupCallValue(not_null<PeerData*> peer) {
|
||||
const auto flag = MTPDchatAdminRights::Flag::f_manage_call;
|
||||
if (const auto chat = peer->asChat()) {
|
||||
return chat->amCreator()
|
||||
? (rpl::single(true) | rpl::type_erased())
|
||||
: AdminRightValue(chat, flag);
|
||||
} else if (const auto channel = peer->asChannel()) {
|
||||
return channel->amCreator()
|
||||
? (rpl::single(true) | rpl::type_erased())
|
||||
: AdminRightValue(channel, flag);
|
||||
}
|
||||
return rpl::single(false);
|
||||
}
|
||||
|
||||
TimeId SortByOnlineValue(not_null<UserData*> user, TimeId now) {
|
||||
if (user->isServiceUser() || user->isBot()) {
|
||||
return -1;
|
||||
|
|
|
@ -111,6 +111,7 @@ inline auto PeerFullFlagValue(
|
|||
[[nodiscard]] rpl::producer<bool> CanWriteValue(ChannelData *channel);
|
||||
[[nodiscard]] rpl::producer<bool> CanWriteValue(not_null<PeerData*> peer);
|
||||
[[nodiscard]] rpl::producer<bool> CanPinMessagesValue(not_null<PeerData*> peer);
|
||||
[[nodiscard]] rpl::producer<bool> CanManageGroupCallValue(not_null<PeerData*> peer);
|
||||
|
||||
[[nodiscard]] TimeId SortByOnlineValue(not_null<UserData*> user, TimeId now);
|
||||
[[nodiscard]] crl::time OnlineChangeTimeout(TimeId online, TimeId now);
|
||||
|
|
|
@ -102,21 +102,7 @@ auto MuteBlobs() {
|
|||
auto Colors() {
|
||||
using Vector = std::vector<QColor>;
|
||||
using Colors = anim::gradient_colors;
|
||||
return base::flat_map<CallMuteButtonType, Colors>{
|
||||
{
|
||||
CallMuteButtonType::ForceMuted,
|
||||
Colors(QGradientStops{
|
||||
{ .0, st::groupCallForceMuted3->c },
|
||||
{ .5, st::groupCallForceMuted2->c },
|
||||
{ 1., st::groupCallForceMuted1->c } })
|
||||
},
|
||||
{
|
||||
CallMuteButtonType::RaisedHand,
|
||||
Colors(QGradientStops{
|
||||
{ .0, st::groupCallForceMuted3->c },
|
||||
{ .5, st::groupCallForceMuted2->c },
|
||||
{ 1., st::groupCallForceMuted1->c } })
|
||||
},
|
||||
auto result = base::flat_map<CallMuteButtonType, Colors>{
|
||||
{
|
||||
CallMuteButtonType::Active,
|
||||
Colors(Vector{ st::groupCallLive1->c, st::groupCallLive2->c })
|
||||
|
@ -130,6 +116,21 @@ auto Colors() {
|
|||
Colors(Vector{ st::groupCallMuted1->c, st::groupCallMuted2->c })
|
||||
},
|
||||
};
|
||||
const auto forceMutedColors = Colors(QGradientStops{
|
||||
{ .0, st::groupCallForceMuted3->c },
|
||||
{ .5, st::groupCallForceMuted2->c },
|
||||
{ 1., st::groupCallForceMuted1->c } });
|
||||
const auto forceMutedTypes = {
|
||||
CallMuteButtonType::ForceMuted,
|
||||
CallMuteButtonType::RaisedHand,
|
||||
CallMuteButtonType::ScheduledCanStart,
|
||||
CallMuteButtonType::ScheduledNotify,
|
||||
CallMuteButtonType::ScheduledSilent,
|
||||
};
|
||||
for (const auto type : forceMutedTypes) {
|
||||
result.emplace(type, forceMutedColors);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool IsMuted(CallMuteButtonType type) {
|
||||
|
@ -143,7 +144,10 @@ bool IsConnecting(CallMuteButtonType type) {
|
|||
bool IsInactive(CallMuteButtonType type) {
|
||||
return IsConnecting(type)
|
||||
|| (type == CallMuteButtonType::ForceMuted)
|
||||
|| (type == CallMuteButtonType::RaisedHand);
|
||||
|| (type == CallMuteButtonType::RaisedHand)
|
||||
|| (type == CallMuteButtonType::ScheduledCanStart)
|
||||
|| (type == CallMuteButtonType::ScheduledNotify)
|
||||
|| (type == CallMuteButtonType::ScheduledSilent);
|
||||
}
|
||||
|
||||
auto Clamp(float64 value) {
|
||||
|
@ -585,6 +589,9 @@ CallMuteButton::IconState CallMuteButton::iconStateFrom(
|
|||
.frameTo = 62,
|
||||
};
|
||||
} break;
|
||||
case CallMuteButtonType::ScheduledCanStart: // #TODO voice chats
|
||||
case CallMuteButtonType::ScheduledNotify:
|
||||
case CallMuteButtonType::ScheduledSilent:
|
||||
case CallMuteButtonType::ForceMuted:
|
||||
case CallMuteButtonType::RaisedHand: {
|
||||
return { // Active -> Hand
|
||||
|
@ -615,6 +622,9 @@ CallMuteButton::IconState CallMuteButton::iconStateFrom(
|
|||
.frameTo = 22,
|
||||
};
|
||||
} break;
|
||||
case CallMuteButtonType::ScheduledCanStart: // #TODO voice chats
|
||||
case CallMuteButtonType::ScheduledNotify:
|
||||
case CallMuteButtonType::ScheduledSilent:
|
||||
case CallMuteButtonType::ForceMuted:
|
||||
case CallMuteButtonType::RaisedHand: {
|
||||
return { // Muted -> Hand
|
||||
|
@ -626,6 +636,9 @@ CallMuteButton::IconState CallMuteButton::iconStateFrom(
|
|||
} break;
|
||||
}
|
||||
} break;
|
||||
case CallMuteButtonType::ScheduledCanStart: // #TODO voice chats
|
||||
case CallMuteButtonType::ScheduledNotify:
|
||||
case CallMuteButtonType::ScheduledSilent:
|
||||
case CallMuteButtonType::ForceMuted:
|
||||
case CallMuteButtonType::RaisedHand: {
|
||||
switch (current) {
|
||||
|
@ -645,6 +658,9 @@ CallMuteButton::IconState CallMuteButton::iconStateFrom(
|
|||
.frameTo = 20,
|
||||
};
|
||||
} break;
|
||||
case CallMuteButtonType::ScheduledCanStart: // #TODO voice chats
|
||||
case CallMuteButtonType::ScheduledNotify:
|
||||
case CallMuteButtonType::ScheduledSilent:
|
||||
case CallMuteButtonType::ForceMuted:
|
||||
case CallMuteButtonType::RaisedHand: {
|
||||
return { // Hand
|
||||
|
@ -1015,6 +1031,9 @@ CallMuteButton::HandleMouseState CallMuteButton::HandleMouseStateFromType(
|
|||
return HandleMouseState::Enabled;
|
||||
case CallMuteButtonType::Connecting:
|
||||
return HandleMouseState::Disabled;
|
||||
case CallMuteButtonType::ScheduledCanStart:
|
||||
case CallMuteButtonType::ScheduledNotify:
|
||||
case CallMuteButtonType::ScheduledSilent:
|
||||
case CallMuteButtonType::ForceMuted:
|
||||
case CallMuteButtonType::RaisedHand:
|
||||
return HandleMouseState::Enabled;
|
||||
|
@ -1098,7 +1117,10 @@ void CallMuteButton::overridesColors(
|
|||
float64 progress) {
|
||||
const auto forceMutedToConnecting = [](CallMuteButtonType &type) {
|
||||
if (type == CallMuteButtonType::ForceMuted
|
||||
|| type == CallMuteButtonType::RaisedHand) {
|
||||
|| type == CallMuteButtonType::RaisedHand
|
||||
|| type == CallMuteButtonType::ScheduledCanStart
|
||||
|| type == CallMuteButtonType::ScheduledNotify
|
||||
|| type == CallMuteButtonType::ScheduledSilent) {
|
||||
type = CallMuteButtonType::Connecting;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -30,6 +30,9 @@ enum class CallMuteButtonType {
|
|||
Muted,
|
||||
ForceMuted,
|
||||
RaisedHand,
|
||||
ScheduledCanStart,
|
||||
ScheduledSilent,
|
||||
ScheduledNotify,
|
||||
};
|
||||
|
||||
struct CallMuteButtonState {
|
||||
|
|
Loading…
Add table
Reference in a new issue