Remove 100% from voice chat 'speaking' status.
This commit is contained in:
parent
4d24f28fd0
commit
8ca622d077
|
@ -205,17 +205,17 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
struct StatusIcon {
|
struct StatusIcon {
|
||||||
StatusIcon(float volume)
|
StatusIcon(bool shown, float volume);
|
||||||
: speaker(st::groupCallStatusSpeakerIcon)
|
|
||||||
, arcs(std::make_unique<Ui::Paint::ArcsAnimation>(
|
|
||||||
st::groupCallStatusSpeakerArcsAnimation,
|
|
||||||
kSpeakerThreshold,
|
|
||||||
volume,
|
|
||||||
Ui::Paint::ArcsAnimation::Direction::Right)) {
|
|
||||||
}
|
|
||||||
const style::icon &speaker;
|
const style::icon &speaker;
|
||||||
const std::unique_ptr<Ui::Paint::ArcsAnimation> arcs;
|
Ui::Paint::ArcsAnimation arcs;
|
||||||
|
Ui::Animations::Simple arcsAnimation;
|
||||||
|
Ui::Animations::Simple shownAnimation;
|
||||||
|
QString percent;
|
||||||
|
int percentWidth = 0;
|
||||||
int arcsWidth = 0;
|
int arcsWidth = 0;
|
||||||
|
int wasArcsWidth = 0;
|
||||||
|
bool shown = true;
|
||||||
|
|
||||||
rpl::lifetime lifetime;
|
rpl::lifetime lifetime;
|
||||||
};
|
};
|
||||||
|
@ -247,7 +247,6 @@ private:
|
||||||
Ui::Animations::Simple _speakingAnimation; // For gray-red/green icon.
|
Ui::Animations::Simple _speakingAnimation; // For gray-red/green icon.
|
||||||
Ui::Animations::Simple _mutedAnimation; // For gray/red icon.
|
Ui::Animations::Simple _mutedAnimation; // For gray/red icon.
|
||||||
Ui::Animations::Simple _activeAnimation; // For icon cross animation.
|
Ui::Animations::Simple _activeAnimation; // For icon cross animation.
|
||||||
Ui::Animations::Simple _arcsAnimation; // For volume arcs animation.
|
|
||||||
QString _aboutText;
|
QString _aboutText;
|
||||||
crl::time _speakingLastTime = 0;
|
crl::time _speakingLastTime = 0;
|
||||||
uint64 _raisedHandRating = 0;
|
uint64 _raisedHandRating = 0;
|
||||||
|
@ -373,6 +372,26 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
[[nodiscard]] QString StatusPercentString(float volume) {
|
||||||
|
return QString::number(int(std::round(volume * 200))) + '%';
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] int StatusPercentWidth(const QString &percent) {
|
||||||
|
return st::normalFont->width(percent);
|
||||||
|
}
|
||||||
|
|
||||||
|
Row::StatusIcon::StatusIcon(bool shown, float volume)
|
||||||
|
: speaker(st::groupCallStatusSpeakerIcon)
|
||||||
|
, arcs(
|
||||||
|
st::groupCallStatusSpeakerArcsAnimation,
|
||||||
|
kSpeakerThreshold,
|
||||||
|
volume,
|
||||||
|
Ui::Paint::ArcsAnimation::Direction::Right)
|
||||||
|
, percent(StatusPercentString(volume))
|
||||||
|
, percentWidth(StatusPercentWidth(percent))
|
||||||
|
, shown(shown) {
|
||||||
|
}
|
||||||
|
|
||||||
Row::Row(
|
Row::Row(
|
||||||
not_null<RowDelegate*> delegate,
|
not_null<RowDelegate*> delegate,
|
||||||
not_null<PeerData*> participantPeer)
|
not_null<PeerData*> participantPeer)
|
||||||
|
@ -433,32 +452,30 @@ void Row::setSpeaking(bool speaking) {
|
||||||
|| (_state == State::MutedByMe)
|
|| (_state == State::MutedByMe)
|
||||||
|| (_state == State::Muted)
|
|| (_state == State::Muted)
|
||||||
|| (_state == State::RaisedHand)) {
|
|| (_state == State::RaisedHand)) {
|
||||||
_statusIcon = nullptr;
|
if (_statusIcon) {
|
||||||
|
_statusIcon = nullptr;
|
||||||
|
_delegate->rowUpdateRow(this);
|
||||||
|
}
|
||||||
} else if (!_statusIcon) {
|
} else if (!_statusIcon) {
|
||||||
_statusIcon = std::make_unique<StatusIcon>(
|
_statusIcon = std::make_unique<StatusIcon>(
|
||||||
|
(_volume != Group::kDefaultVolume),
|
||||||
(float)_volume / Group::kMaxVolume);
|
(float)_volume / Group::kMaxVolume);
|
||||||
_statusIcon->arcs->setStrokeRatio(kArcsStrokeRatio);
|
_statusIcon->arcs.setStrokeRatio(kArcsStrokeRatio);
|
||||||
_statusIcon->arcsWidth = _statusIcon->arcs->finishedWidth();
|
_statusIcon->arcsWidth = _statusIcon->arcs.finishedWidth();
|
||||||
|
_statusIcon->arcs.startUpdateRequests(
|
||||||
const auto wasArcsWidth = _statusIcon->lifetime.make_state<int>(0);
|
|
||||||
|
|
||||||
_statusIcon->arcs->startUpdateRequests(
|
|
||||||
) | rpl::start_with_next([=] {
|
) | rpl::start_with_next([=] {
|
||||||
if (!_arcsAnimation.animating()) {
|
if (!_statusIcon->arcsAnimation.animating()) {
|
||||||
*wasArcsWidth = _statusIcon->arcsWidth;
|
_statusIcon->wasArcsWidth = _statusIcon->arcsWidth;
|
||||||
}
|
}
|
||||||
auto callback = [=](float64 value) {
|
auto callback = [=](float64 value) {
|
||||||
if (_statusIcon) {
|
_statusIcon->arcs.update(crl::now());
|
||||||
_statusIcon->arcs->update(crl::now());
|
_statusIcon->arcsWidth = anim::interpolate(
|
||||||
|
_statusIcon->wasArcsWidth,
|
||||||
_statusIcon->arcsWidth = anim::interpolate(
|
_statusIcon->arcs.finishedWidth(),
|
||||||
*wasArcsWidth,
|
value);
|
||||||
_statusIcon->arcs->finishedWidth(),
|
|
||||||
value);
|
|
||||||
}
|
|
||||||
_delegate->rowUpdateRow(this);
|
_delegate->rowUpdateRow(this);
|
||||||
};
|
};
|
||||||
_arcsAnimation.start(
|
_statusIcon->arcsAnimation.start(
|
||||||
std::move(callback),
|
std::move(callback),
|
||||||
0.,
|
0.,
|
||||||
1.,
|
1.,
|
||||||
|
@ -533,7 +550,20 @@ void Row::setSsrc(uint32 ssrc) {
|
||||||
void Row::setVolume(int volume) {
|
void Row::setVolume(int volume) {
|
||||||
_volume = volume;
|
_volume = volume;
|
||||||
if (_statusIcon) {
|
if (_statusIcon) {
|
||||||
_statusIcon->arcs->setValue((float)volume / Group::kMaxVolume);
|
const auto floatVolume = (float)volume / Group::kMaxVolume;
|
||||||
|
_statusIcon->arcs.setValue(floatVolume);
|
||||||
|
_statusIcon->percent = StatusPercentString(floatVolume);
|
||||||
|
_statusIcon->percentWidth = StatusPercentWidth(_statusIcon->percent);
|
||||||
|
|
||||||
|
const auto shown = (volume != Group::kDefaultVolume);
|
||||||
|
if (_statusIcon->shown != shown) {
|
||||||
|
_statusIcon->shown = shown;
|
||||||
|
_statusIcon->shownAnimation.start(
|
||||||
|
[=] { _delegate->rowUpdateRow(this); },
|
||||||
|
shown ? 0. : 1.,
|
||||||
|
shown ? 1. : 0.,
|
||||||
|
st::groupCallSpeakerArcsAnimation.duration);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -658,21 +688,20 @@ auto Row::generatePaintUserpicCallback() -> PaintRoundImageCallback {
|
||||||
}
|
}
|
||||||
|
|
||||||
int Row::statusIconWidth() const {
|
int Row::statusIconWidth() const {
|
||||||
if (!_statusIcon) {
|
if (!_statusIcon || !_speaking) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return _speaking
|
const auto shown = _statusIcon->shownAnimation.value(
|
||||||
? (_statusIcon->speaker.width() + _statusIcon->arcsWidth)
|
_statusIcon->shown ? 1. : 0.);
|
||||||
: 0;
|
const auto full = _statusIcon->speaker.width()
|
||||||
|
+ _statusIcon->arcsWidth
|
||||||
|
+ _statusIcon->percentWidth
|
||||||
|
+ st::normalFont->spacew;
|
||||||
|
return int(std::round(shown * full));
|
||||||
}
|
}
|
||||||
|
|
||||||
int Row::statusIconHeight() const {
|
int Row::statusIconHeight() const {
|
||||||
if (!_statusIcon) {
|
return (_statusIcon && _speaking) ? _statusIcon->speaker.height() : 0;
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return _speaking
|
|
||||||
? _statusIcon->speaker.height()
|
|
||||||
: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Row::paintStatusIcon(
|
void Row::paintStatusIcon(
|
||||||
|
@ -683,6 +712,12 @@ void Row::paintStatusIcon(
|
||||||
if (!_statusIcon) {
|
if (!_statusIcon) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const auto shown = _statusIcon->shownAnimation.value(
|
||||||
|
_statusIcon->shown ? 1. : 0.);
|
||||||
|
if (shown == 0.) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
p.setFont(font);
|
p.setFont(font);
|
||||||
const auto color = (_speaking
|
const auto color = (_speaking
|
||||||
? st.statusFgActive
|
? st.statusFgActive
|
||||||
|
@ -697,17 +732,34 @@ void Row::paintStatusIcon(
|
||||||
+ QPoint(
|
+ QPoint(
|
||||||
speakerRect.width() - st::groupCallStatusSpeakerArcsSkip,
|
speakerRect.width() - st::groupCallStatusSpeakerArcsSkip,
|
||||||
speakerRect.height() / 2);
|
speakerRect.height() / 2);
|
||||||
|
const auto fullWidth = speakerRect.width()
|
||||||
|
+ _statusIcon->arcsWidth
|
||||||
|
+ _statusIcon->percentWidth
|
||||||
|
+ st::normalFont->spacew;
|
||||||
|
|
||||||
const auto volume = std::round(_volume / 100.);
|
p.save();
|
||||||
|
if (shown < 1.) {
|
||||||
|
const auto centerx = speakerRect.x() + fullWidth / 2;
|
||||||
|
const auto centery = speakerRect.y() + speakerRect.height() / 2;
|
||||||
|
p.translate(centerx, centery);
|
||||||
|
p.scale(shown, shown);
|
||||||
|
p.translate(-centerx, -centery);
|
||||||
|
}
|
||||||
_statusIcon->speaker.paint(
|
_statusIcon->speaker.paint(
|
||||||
p,
|
p,
|
||||||
speakerRect.topLeft(),
|
speakerRect.topLeft(),
|
||||||
speakerRect.width(),
|
speakerRect.width(),
|
||||||
color);
|
color);
|
||||||
|
|
||||||
p.save();
|
|
||||||
p.translate(arcPosition);
|
p.translate(arcPosition);
|
||||||
_statusIcon->arcs->paint(p, color);
|
_statusIcon->arcs.paint(p, color);
|
||||||
|
p.translate(-arcPosition);
|
||||||
|
p.setFont(st::normalFont);
|
||||||
|
p.setPen(st.statusFgActive);
|
||||||
|
p.drawTextLeft(
|
||||||
|
st.statusPosition.x() + speakerRect.width() + _statusIcon->arcsWidth,
|
||||||
|
st.statusPosition.y(),
|
||||||
|
fullWidth,
|
||||||
|
_statusIcon->percent);
|
||||||
p.restore();
|
p.restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -736,11 +788,14 @@ void Row::paintStatusText(
|
||||||
if (about.isEmpty()
|
if (about.isEmpty()
|
||||||
&& _state != State::Invited
|
&& _state != State::Invited
|
||||||
&& _state != State::MutedByMe) {
|
&& _state != State::MutedByMe) {
|
||||||
p.save();
|
|
||||||
paintStatusIcon(p, st, font, selected);
|
paintStatusIcon(p, st, font, selected);
|
||||||
|
|
||||||
const auto translatedWidth = statusIconWidth();
|
const auto translatedWidth = statusIconWidth();
|
||||||
p.translate(translatedWidth, 0);
|
p.translate(translatedWidth, 0);
|
||||||
const auto guard = gsl::finally([&] { p.restore(); });
|
const auto guard = gsl::finally([&] {
|
||||||
|
p.translate(-translatedWidth, 0);
|
||||||
|
});
|
||||||
|
|
||||||
PeerListRow::paintStatusText(
|
PeerListRow::paintStatusText(
|
||||||
p,
|
p,
|
||||||
st,
|
st,
|
||||||
|
@ -819,9 +874,7 @@ void Row::paintAction(
|
||||||
void Row::refreshStatus() {
|
void Row::refreshStatus() {
|
||||||
setCustomStatus(
|
setCustomStatus(
|
||||||
(_speaking
|
(_speaking
|
||||||
? u"%1% %2"_q
|
? tr::lng_group_call_active(tr::now)
|
||||||
.arg(std::round(_volume / 100.))
|
|
||||||
.arg(tr::lng_group_call_active(tr::now))
|
|
||||||
: _raisedHandStatus
|
: _raisedHandStatus
|
||||||
? tr::lng_group_call_raised_hand_status(tr::now)
|
? tr::lng_group_call_raised_hand_status(tr::now)
|
||||||
: tr::lng_group_call_inactive(tr::now)),
|
: tr::lng_group_call_inactive(tr::now)),
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit f6a1a44efeba79339bdb114ef9a36a9ba865e64b
|
Subproject commit 91e1979da5394525c8373cfbd19f5593a2f483d7
|
Loading…
Reference in New Issue