mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-03-01 12:00:48 +00:00
Always try to play video in voice chats.
This commit is contained in:
parent
0cfede984c
commit
29c0956d61
@ -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_share" = "Share Invite Link";
|
||||
"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#other" = "The voice chat is over {count} members.\nNew participants only have access to audio stream.";
|
||||
"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) {
|
||||
call->setInCall();
|
||||
}
|
||||
if (!videoIsWorking()) {
|
||||
refreshHasNotShownVideo();
|
||||
}
|
||||
}
|
||||
|
||||
if (false
|
||||
@ -1100,9 +1097,6 @@ void GroupCall::markEndpointActive(
|
||||
bool paused) {
|
||||
if (!endpoint) {
|
||||
return;
|
||||
} else if (active && !videoIsWorking()) {
|
||||
refreshHasNotShownVideo();
|
||||
return;
|
||||
}
|
||||
const auto i = _activeVideoTracks.find(endpoint);
|
||||
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() {
|
||||
const auto real = lookupReal();
|
||||
Assert(real != nullptr);
|
||||
@ -2641,9 +2619,7 @@ void GroupCall::fillActiveVideoEndpoints() {
|
||||
const auto me = real->participantByPeer(_joinAs);
|
||||
if (me && me->videoJoined) {
|
||||
_videoIsWorking = true;
|
||||
_hasNotShownVideo = false;
|
||||
} else {
|
||||
refreshHasNotShownVideo();
|
||||
_videoIsWorking = false;
|
||||
toggleVideo(false);
|
||||
toggleScreenSharing(std::nullopt);
|
||||
@ -2671,30 +2647,28 @@ void GroupCall::fillActiveVideoEndpoints() {
|
||||
}
|
||||
};
|
||||
using Type = VideoEndpointType;
|
||||
if (_videoIsWorking.current()) {
|
||||
for (const auto &participant : real->participants()) {
|
||||
const auto camera = GetCameraEndpoint(participant.videoParams);
|
||||
if (camera != _cameraEndpoint
|
||||
&& camera != _screenEndpoint
|
||||
&& participant.peer != _joinAs) {
|
||||
const auto paused = IsCameraPaused(participant.videoParams);
|
||||
feedOne({ Type::Camera, participant.peer, camera }, paused);
|
||||
}
|
||||
const auto screen = GetScreenEndpoint(participant.videoParams);
|
||||
if (screen != _cameraEndpoint
|
||||
&& screen != _screenEndpoint
|
||||
&& participant.peer != _joinAs) {
|
||||
const auto paused = IsScreenPaused(participant.videoParams);
|
||||
feedOne({ Type::Screen, participant.peer, screen }, paused);
|
||||
}
|
||||
for (const auto &participant : real->participants()) {
|
||||
const auto camera = GetCameraEndpoint(participant.videoParams);
|
||||
if (camera != _cameraEndpoint
|
||||
&& camera != _screenEndpoint
|
||||
&& participant.peer != _joinAs) {
|
||||
const auto paused = IsCameraPaused(participant.videoParams);
|
||||
feedOne({ Type::Camera, participant.peer, camera }, paused);
|
||||
}
|
||||
const auto screen = GetScreenEndpoint(participant.videoParams);
|
||||
if (screen != _cameraEndpoint
|
||||
&& screen != _screenEndpoint
|
||||
&& participant.peer != _joinAs) {
|
||||
const auto paused = IsScreenPaused(participant.videoParams);
|
||||
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) {
|
||||
setVideoEndpointLarge({});
|
||||
}
|
||||
|
@ -362,12 +362,6 @@ public:
|
||||
[[nodiscard]] rpl::producer<bool> videoIsWorkingValue() const {
|
||||
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);
|
||||
[[nodiscard]] bool isSharingScreen() const;
|
||||
@ -521,7 +515,6 @@ private:
|
||||
void updateRequestedVideoChannels();
|
||||
void updateRequestedVideoChannelsDelayed();
|
||||
void fillActiveVideoEndpoints();
|
||||
void refreshHasNotShownVideo();
|
||||
|
||||
void editParticipant(
|
||||
not_null<PeerData*> participantPeer,
|
||||
@ -580,7 +573,6 @@ private:
|
||||
rpl::variable<MuteState> _muted = MuteState::Muted;
|
||||
rpl::variable<bool> _canManage = false;
|
||||
rpl::variable<bool> _videoIsWorking = false;
|
||||
rpl::variable<bool> _hasNotShownVideo = false;
|
||||
bool _initialMuteStateSent = false;
|
||||
bool _acceptFields = false;
|
||||
|
||||
|
@ -46,125 +46,6 @@ constexpr auto kUserpicBlurRadius = 8;
|
||||
|
||||
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
|
||||
|
||||
class Members::Controller final
|
||||
@ -1658,8 +1539,6 @@ Members::Members(
|
||||
, _layout(_scroll->setOwnedWidget(
|
||||
object_ptr<Ui::VerticalLayout>(_scroll.data())))
|
||||
, _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(
|
||||
std::make_unique<Viewport>(
|
||||
_videoWrap.get(),
|
||||
@ -1897,61 +1776,9 @@ void Members::trackViewportGeometry() {
|
||||
_scroll->scrollTopValue(
|
||||
) | rpl::skip(1) | rpl::start_with_next(move, _viewport->lifetime());
|
||||
|
||||
const auto videoLimit = VideoParticipantsLimit(&_call->peer()->session());
|
||||
rpl::combine(
|
||||
_layout->widthValue(),
|
||||
_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))));
|
||||
_viewport->fullHeightValue(
|
||||
) | rpl::start_with_next([=](int viewport) {
|
||||
_videoWrap->resize(_videoWrap->width(), viewport);
|
||||
if (viewport > 0) {
|
||||
move();
|
||||
resize();
|
||||
|
@ -101,8 +101,6 @@ private:
|
||||
std::unique_ptr<Controller> _listController;
|
||||
not_null<Ui::VerticalLayout*> _layout;
|
||||
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;
|
||||
rpl::variable<Ui::RpWidget*> _addMemberButton = nullptr;
|
||||
RpWidget *_topSkip = nullptr;
|
||||
|
Loading…
Reference in New Issue
Block a user