mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Always try to play video in voice chats.
This commit is contained in:
parent
0cfede984c
commit
29c0956d61
5 changed files with 23 additions and 234 deletions
|
@ -2103,8 +2103,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_group_call_ptt_delay" = "Push to Talk release delay: {delay}";
|
"lng_group_call_ptt_delay" = "Push to Talk release delay: {delay}";
|
||||||
"lng_group_call_share" = "Share Invite Link";
|
"lng_group_call_share" = "Share Invite Link";
|
||||||
"lng_group_call_noise_suppression" = "Enable Noise Suppression";
|
"lng_group_call_noise_suppression" = "Enable Noise Suppression";
|
||||||
"lng_group_call_limit#one" = "Video is only available\nfor the first {count} member";
|
|
||||||
"lng_group_call_limit#other" = "Video is only available\nfor the first {count} members";
|
|
||||||
"lng_group_call_over_limit#one" = "The voice chat is over {count} member.\nNew participants only have access to audio stream.";
|
"lng_group_call_over_limit#one" = "The voice chat is over {count} member.\nNew participants only have access to audio stream.";
|
||||||
"lng_group_call_over_limit#other" = "The voice chat is over {count} members.\nNew participants only have access to audio stream.";
|
"lng_group_call_over_limit#other" = "The voice chat is over {count} members.\nNew participants only have access to audio stream.";
|
||||||
"lng_group_call_video_paused" = "Video is paused";
|
"lng_group_call_video_paused" = "Video is paused";
|
||||||
|
|
|
@ -885,9 +885,6 @@ void GroupCall::setState(State state) {
|
||||||
if (const auto call = _peer->groupCall(); call && call->id() == _id) {
|
if (const auto call = _peer->groupCall(); call && call->id() == _id) {
|
||||||
call->setInCall();
|
call->setInCall();
|
||||||
}
|
}
|
||||||
if (!videoIsWorking()) {
|
|
||||||
refreshHasNotShownVideo();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (false
|
if (false
|
||||||
|
@ -1100,9 +1097,6 @@ void GroupCall::markEndpointActive(
|
||||||
bool paused) {
|
bool paused) {
|
||||||
if (!endpoint) {
|
if (!endpoint) {
|
||||||
return;
|
return;
|
||||||
} else if (active && !videoIsWorking()) {
|
|
||||||
refreshHasNotShownVideo();
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
const auto i = _activeVideoTracks.find(endpoint);
|
const auto i = _activeVideoTracks.find(endpoint);
|
||||||
const auto changed = active
|
const auto changed = active
|
||||||
|
@ -2618,22 +2612,6 @@ void GroupCall::updateRequestedVideoChannelsDelayed() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void GroupCall::refreshHasNotShownVideo() {
|
|
||||||
if (!_joinState.ssrc || hasNotShownVideo()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const auto real = lookupReal();
|
|
||||||
Assert(real != nullptr);
|
|
||||||
|
|
||||||
const auto hasVideo = [&](const Data::GroupCallParticipant &data) {
|
|
||||||
return (data.peer != _joinAs)
|
|
||||||
&& (!GetCameraEndpoint(data.videoParams).empty()
|
|
||||||
|| !GetScreenEndpoint(data.videoParams).empty());
|
|
||||||
};
|
|
||||||
_hasNotShownVideo = _joinState.ssrc
|
|
||||||
&& ranges::any_of(real->participants(), hasVideo);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GroupCall::fillActiveVideoEndpoints() {
|
void GroupCall::fillActiveVideoEndpoints() {
|
||||||
const auto real = lookupReal();
|
const auto real = lookupReal();
|
||||||
Assert(real != nullptr);
|
Assert(real != nullptr);
|
||||||
|
@ -2641,9 +2619,7 @@ void GroupCall::fillActiveVideoEndpoints() {
|
||||||
const auto me = real->participantByPeer(_joinAs);
|
const auto me = real->participantByPeer(_joinAs);
|
||||||
if (me && me->videoJoined) {
|
if (me && me->videoJoined) {
|
||||||
_videoIsWorking = true;
|
_videoIsWorking = true;
|
||||||
_hasNotShownVideo = false;
|
|
||||||
} else {
|
} else {
|
||||||
refreshHasNotShownVideo();
|
|
||||||
_videoIsWorking = false;
|
_videoIsWorking = false;
|
||||||
toggleVideo(false);
|
toggleVideo(false);
|
||||||
toggleScreenSharing(std::nullopt);
|
toggleScreenSharing(std::nullopt);
|
||||||
|
@ -2671,30 +2647,28 @@ void GroupCall::fillActiveVideoEndpoints() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
using Type = VideoEndpointType;
|
using Type = VideoEndpointType;
|
||||||
if (_videoIsWorking.current()) {
|
for (const auto &participant : real->participants()) {
|
||||||
for (const auto &participant : real->participants()) {
|
const auto camera = GetCameraEndpoint(participant.videoParams);
|
||||||
const auto camera = GetCameraEndpoint(participant.videoParams);
|
if (camera != _cameraEndpoint
|
||||||
if (camera != _cameraEndpoint
|
&& camera != _screenEndpoint
|
||||||
&& camera != _screenEndpoint
|
&& participant.peer != _joinAs) {
|
||||||
&& participant.peer != _joinAs) {
|
const auto paused = IsCameraPaused(participant.videoParams);
|
||||||
const auto paused = IsCameraPaused(participant.videoParams);
|
feedOne({ Type::Camera, participant.peer, camera }, paused);
|
||||||
feedOne({ Type::Camera, participant.peer, camera }, paused);
|
}
|
||||||
}
|
const auto screen = GetScreenEndpoint(participant.videoParams);
|
||||||
const auto screen = GetScreenEndpoint(participant.videoParams);
|
if (screen != _cameraEndpoint
|
||||||
if (screen != _cameraEndpoint
|
&& screen != _screenEndpoint
|
||||||
&& screen != _screenEndpoint
|
&& participant.peer != _joinAs) {
|
||||||
&& participant.peer != _joinAs) {
|
const auto paused = IsScreenPaused(participant.videoParams);
|
||||||
const auto paused = IsScreenPaused(participant.videoParams);
|
feedOne({ Type::Screen, participant.peer, screen }, paused);
|
||||||
feedOne({ Type::Screen, participant.peer, screen }, paused);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
feedOne(
|
|
||||||
{ Type::Camera, _joinAs, cameraSharingEndpoint() },
|
|
||||||
isCameraPaused());
|
|
||||||
feedOne(
|
|
||||||
{ Type::Screen, _joinAs, screenSharingEndpoint() },
|
|
||||||
isScreenPaused());
|
|
||||||
}
|
}
|
||||||
|
feedOne(
|
||||||
|
{ Type::Camera, _joinAs, cameraSharingEndpoint() },
|
||||||
|
isCameraPaused());
|
||||||
|
feedOne(
|
||||||
|
{ Type::Screen, _joinAs, screenSharingEndpoint() },
|
||||||
|
isScreenPaused());
|
||||||
if (large && !largeFound) {
|
if (large && !largeFound) {
|
||||||
setVideoEndpointLarge({});
|
setVideoEndpointLarge({});
|
||||||
}
|
}
|
||||||
|
|
|
@ -362,12 +362,6 @@ public:
|
||||||
[[nodiscard]] rpl::producer<bool> videoIsWorkingValue() const {
|
[[nodiscard]] rpl::producer<bool> videoIsWorkingValue() const {
|
||||||
return _videoIsWorking.value();
|
return _videoIsWorking.value();
|
||||||
}
|
}
|
||||||
[[nodiscard]] bool hasNotShownVideo() const {
|
|
||||||
return _hasNotShownVideo.current();
|
|
||||||
}
|
|
||||||
[[nodiscard]] rpl::producer<bool> hasNotShownVideoValue() const {
|
|
||||||
return _hasNotShownVideo.value();
|
|
||||||
}
|
|
||||||
|
|
||||||
void setCurrentAudioDevice(bool input, const QString &deviceId);
|
void setCurrentAudioDevice(bool input, const QString &deviceId);
|
||||||
[[nodiscard]] bool isSharingScreen() const;
|
[[nodiscard]] bool isSharingScreen() const;
|
||||||
|
@ -521,7 +515,6 @@ private:
|
||||||
void updateRequestedVideoChannels();
|
void updateRequestedVideoChannels();
|
||||||
void updateRequestedVideoChannelsDelayed();
|
void updateRequestedVideoChannelsDelayed();
|
||||||
void fillActiveVideoEndpoints();
|
void fillActiveVideoEndpoints();
|
||||||
void refreshHasNotShownVideo();
|
|
||||||
|
|
||||||
void editParticipant(
|
void editParticipant(
|
||||||
not_null<PeerData*> participantPeer,
|
not_null<PeerData*> participantPeer,
|
||||||
|
@ -580,7 +573,6 @@ private:
|
||||||
rpl::variable<MuteState> _muted = MuteState::Muted;
|
rpl::variable<MuteState> _muted = MuteState::Muted;
|
||||||
rpl::variable<bool> _canManage = false;
|
rpl::variable<bool> _canManage = false;
|
||||||
rpl::variable<bool> _videoIsWorking = false;
|
rpl::variable<bool> _videoIsWorking = false;
|
||||||
rpl::variable<bool> _hasNotShownVideo = false;
|
|
||||||
bool _initialMuteStateSent = false;
|
bool _initialMuteStateSent = false;
|
||||||
bool _acceptFields = false;
|
bool _acceptFields = false;
|
||||||
|
|
||||||
|
|
|
@ -46,125 +46,6 @@ constexpr auto kUserpicBlurRadius = 8;
|
||||||
|
|
||||||
using Row = MembersRow;
|
using Row = MembersRow;
|
||||||
|
|
||||||
[[nodiscard]] int VideoParticipantsLimit(not_null<Main::Session*> session) {
|
|
||||||
return int(session->account().appConfig().get<double>(
|
|
||||||
"groupcall_video_participants_max",
|
|
||||||
30.));
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetupVideoPlaceholder(
|
|
||||||
not_null<Ui::RpWidget*> widget,
|
|
||||||
not_null<PeerData*> chat,
|
|
||||||
int limit) {
|
|
||||||
struct State {
|
|
||||||
QImage blurred;
|
|
||||||
QImage rounded;
|
|
||||||
InMemoryKey key = {};
|
|
||||||
std::shared_ptr<Data::CloudImageView> view;
|
|
||||||
qint64 blurredCacheKey = 0;
|
|
||||||
};
|
|
||||||
const auto state = widget->lifetime().make_state<State>();
|
|
||||||
const auto refreshBlurred = [=] {
|
|
||||||
const auto key = chat->userpicUniqueKey(state->view);
|
|
||||||
if (state->key == key && !state->blurred.isNull()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
constexpr auto size = kUserpicSizeForBlur;
|
|
||||||
state->key = key;
|
|
||||||
state->blurred = QImage(
|
|
||||||
QSize(size, size),
|
|
||||||
QImage::Format_ARGB32_Premultiplied);
|
|
||||||
{
|
|
||||||
auto p = Painter(&state->blurred);
|
|
||||||
auto hq = PainterHighQualityEnabler(p);
|
|
||||||
chat->paintUserpicSquare(p, state->view, 0, 0, size);
|
|
||||||
}
|
|
||||||
state->blurred = Images::BlurLargeImage(
|
|
||||||
std::move(state->blurred),
|
|
||||||
kUserpicBlurRadius);
|
|
||||||
widget->update();
|
|
||||||
};
|
|
||||||
const auto refreshRounded = [=](QSize size) {
|
|
||||||
refreshBlurred();
|
|
||||||
const auto key = state->blurred.cacheKey();
|
|
||||||
if (state->rounded.size() == size && state->blurredCacheKey == key) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
state->blurredCacheKey = key;
|
|
||||||
state->rounded = Images::prepare(
|
|
||||||
state->blurred,
|
|
||||||
size.width(),
|
|
||||||
size.width(), // Square
|
|
||||||
Images::Option::Smooth,
|
|
||||||
size.width(),
|
|
||||||
size.height());
|
|
||||||
{
|
|
||||||
auto p = QPainter(&state->rounded);
|
|
||||||
p.fillRect(
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
size.width(),
|
|
||||||
size.height(),
|
|
||||||
QColor(0, 0, 0, Viewport::kShadowMaxAlpha));
|
|
||||||
}
|
|
||||||
state->rounded = Images::prepare(
|
|
||||||
std::move(state->rounded),
|
|
||||||
size.width(),
|
|
||||||
size.height(),
|
|
||||||
(Images::Option::RoundedLarge | Images::Option::RoundedAll),
|
|
||||||
size.width(),
|
|
||||||
size.height());
|
|
||||||
};
|
|
||||||
chat->loadUserpic();
|
|
||||||
refreshBlurred();
|
|
||||||
|
|
||||||
widget->paintRequest(
|
|
||||||
) | rpl::start_with_next([=] {
|
|
||||||
const auto size = QSize(
|
|
||||||
widget->width(),
|
|
||||||
widget->height() - st::groupCallVideoSmallSkip);
|
|
||||||
refreshRounded(size * cIntRetinaFactor());
|
|
||||||
|
|
||||||
auto p = QPainter(widget);
|
|
||||||
const auto inner = QRect(QPoint(), size);
|
|
||||||
p.drawImage(inner, state->rounded);
|
|
||||||
st::groupCallPaused.paint(
|
|
||||||
p,
|
|
||||||
(size.width() - st::groupCallPaused.width()) / 2,
|
|
||||||
st::groupCallVideoPlaceholderIconTop,
|
|
||||||
size.width());
|
|
||||||
|
|
||||||
const auto skip = st::groupCallVideoLargeSkip;
|
|
||||||
p.setPen(st::groupCallVideoTextFg);
|
|
||||||
const auto text = QRect(
|
|
||||||
skip,
|
|
||||||
st::groupCallVideoPlaceholderTextTop,
|
|
||||||
(size.width() - 2 * skip),
|
|
||||||
size.height() - st::groupCallVideoPlaceholderTextTop);
|
|
||||||
p.setFont(st::semiboldFont);
|
|
||||||
p.drawText(
|
|
||||||
text,
|
|
||||||
tr::lng_group_call_limit(tr::now, lt_count, int(limit)),
|
|
||||||
style::al_top);
|
|
||||||
}, widget->lifetime());
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetupVideoAboutLimit(
|
|
||||||
not_null<Ui::RpWidget*> widget,
|
|
||||||
not_null<Main::Session*> session,
|
|
||||||
int limit) {
|
|
||||||
const auto label = Ui::CreateChild<Ui::FlatLabel>(
|
|
||||||
widget.get(),
|
|
||||||
tr::lng_group_call_over_limit(lt_count, rpl::single(limit * 1.)),
|
|
||||||
st::groupCallVideoLimitLabel);
|
|
||||||
widget->widthValue(
|
|
||||||
) | rpl::start_with_next([=](int width) {
|
|
||||||
label->resizeToWidth(width);
|
|
||||||
label->moveToLeft(0, st::normalFont->height / 3);
|
|
||||||
widget->resize(width, label->height() + st::normalFont->height);
|
|
||||||
}, label->lifetime());
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
class Members::Controller final
|
class Members::Controller final
|
||||||
|
@ -1658,8 +1539,6 @@ Members::Members(
|
||||||
, _layout(_scroll->setOwnedWidget(
|
, _layout(_scroll->setOwnedWidget(
|
||||||
object_ptr<Ui::VerticalLayout>(_scroll.data())))
|
object_ptr<Ui::VerticalLayout>(_scroll.data())))
|
||||||
, _videoWrap(_layout->add(object_ptr<Ui::RpWidget>(_layout.get())))
|
, _videoWrap(_layout->add(object_ptr<Ui::RpWidget>(_layout.get())))
|
||||||
, _videoPlaceholder(std::make_unique<Ui::RpWidget>(_videoWrap.get()))
|
|
||||||
, _videoAboutLimit(std::make_unique<Ui::RpWidget>(_videoWrap.get()))
|
|
||||||
, _viewport(
|
, _viewport(
|
||||||
std::make_unique<Viewport>(
|
std::make_unique<Viewport>(
|
||||||
_videoWrap.get(),
|
_videoWrap.get(),
|
||||||
|
@ -1897,61 +1776,9 @@ void Members::trackViewportGeometry() {
|
||||||
_scroll->scrollTopValue(
|
_scroll->scrollTopValue(
|
||||||
) | rpl::skip(1) | rpl::start_with_next(move, _viewport->lifetime());
|
) | rpl::skip(1) | rpl::start_with_next(move, _viewport->lifetime());
|
||||||
|
|
||||||
const auto videoLimit = VideoParticipantsLimit(&_call->peer()->session());
|
_viewport->fullHeightValue(
|
||||||
rpl::combine(
|
) | rpl::start_with_next([=](int viewport) {
|
||||||
_layout->widthValue(),
|
_videoWrap->resize(_videoWrap->width(), viewport);
|
||||||
_call->hasNotShownVideoValue()
|
|
||||||
) | rpl::start_with_next([=](int width, bool has) {
|
|
||||||
const auto height = has ? st::groupCallVideoPlaceholderHeight : 0;
|
|
||||||
_videoPlaceholder->setGeometry(0, 0, width, height);
|
|
||||||
}, _videoPlaceholder->lifetime());
|
|
||||||
|
|
||||||
SetupVideoPlaceholder(_videoPlaceholder.get(), _call->peer(), videoLimit);
|
|
||||||
|
|
||||||
_layout->widthValue(
|
|
||||||
) | rpl::start_with_next([=](int width) {
|
|
||||||
_videoAboutLimit->resizeToWidth(width);
|
|
||||||
}, _videoAboutLimit->lifetime());
|
|
||||||
|
|
||||||
using namespace rpl::mappers;
|
|
||||||
auto aboutLimitRelevant = fullCountValue(
|
|
||||||
) | rpl::map(
|
|
||||||
_1 > videoLimit
|
|
||||||
) | rpl::distinct_until_changed();
|
|
||||||
auto aboutLimitShown = rpl::combine(
|
|
||||||
std::move(aboutLimitRelevant),
|
|
||||||
_call->canManageValue(),
|
|
||||||
_1 && _2);
|
|
||||||
|
|
||||||
SetupVideoAboutLimit(
|
|
||||||
_videoAboutLimit.get(),
|
|
||||||
&_call->peer()->session(),
|
|
||||||
videoLimit);
|
|
||||||
|
|
||||||
rpl::combine(
|
|
||||||
_videoPlaceholder->heightValue(),
|
|
||||||
_viewport->fullHeightValue(),
|
|
||||||
_videoAboutLimit->heightValue(),
|
|
||||||
std::move(aboutLimitShown)
|
|
||||||
) | rpl::start_with_next([=](
|
|
||||||
int placeholder,
|
|
||||||
int viewport,
|
|
||||||
int aboutLimit,
|
|
||||||
bool aboutLimitShown) {
|
|
||||||
if (placeholder > 0 || viewport <= 0 || !aboutLimitShown) {
|
|
||||||
aboutLimitShown = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This call may update _videoAboutLimit->height() :(
|
|
||||||
_videoAboutLimit->setVisible(aboutLimitShown);
|
|
||||||
|
|
||||||
_videoAboutLimit->move(0, viewport);
|
|
||||||
_videoWrap->resize(
|
|
||||||
_videoWrap->width(),
|
|
||||||
std::max(
|
|
||||||
placeholder,
|
|
||||||
(viewport
|
|
||||||
+ (aboutLimitShown ? _videoAboutLimit->height() : 0))));
|
|
||||||
if (viewport > 0) {
|
if (viewport > 0) {
|
||||||
move();
|
move();
|
||||||
resize();
|
resize();
|
||||||
|
|
|
@ -101,8 +101,6 @@ private:
|
||||||
std::unique_ptr<Controller> _listController;
|
std::unique_ptr<Controller> _listController;
|
||||||
not_null<Ui::VerticalLayout*> _layout;
|
not_null<Ui::VerticalLayout*> _layout;
|
||||||
const not_null<Ui::RpWidget*> _videoWrap;
|
const not_null<Ui::RpWidget*> _videoWrap;
|
||||||
const std::unique_ptr<Ui::RpWidget> _videoPlaceholder;
|
|
||||||
const std::unique_ptr<Ui::RpWidget> _videoAboutLimit;
|
|
||||||
std::unique_ptr<Viewport> _viewport;
|
std::unique_ptr<Viewport> _viewport;
|
||||||
rpl::variable<Ui::RpWidget*> _addMemberButton = nullptr;
|
rpl::variable<Ui::RpWidget*> _addMemberButton = nullptr;
|
||||||
RpWidget *_topSkip = nullptr;
|
RpWidget *_topSkip = nullptr;
|
||||||
|
|
Loading…
Add table
Reference in a new issue