| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778 |
- /*
- This file is part of Telegram Desktop,
- the official desktop application for the Telegram messaging service.
- For license and copyright information please follow this link:
- https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
- */
- #include "calls/group/calls_group_members_row.h"
- #include "calls/group/calls_group_call.h"
- #include "calls/group/calls_group_common.h"
- #include "data/data_peer.h"
- #include "data/data_group_call.h"
- #include "ui/paint/arcs.h"
- #include "ui/paint/blobs.h"
- #include "ui/text/text_options.h"
- #include "ui/effects/ripple_animation.h"
- #include "ui/painter.h"
- #include "lang/lang_keys.h"
- #include "webrtc/webrtc_video_track.h"
- #include "styles/style_calls.h"
- namespace Calls::Group {
- namespace {
- constexpr auto kLevelDuration = 100. + 500. * 0.23;
- constexpr auto kBlobScale = 0.605;
- constexpr auto kMinorBlobFactor = 0.9f;
- constexpr auto kUserpicMinScale = 0.8;
- constexpr auto kMaxLevel = 1.;
- constexpr auto kWideScale = 5;
- constexpr auto kArcsStrokeRatio = 0.8;
- const auto kSpeakerThreshold = std::vector<float>{
- Group::kDefaultVolume * 0.1f / Group::kMaxVolume,
- Group::kDefaultVolume * 0.9f / Group::kMaxVolume };
- auto RowBlobs() -> std::array<Ui::Paint::Blobs::BlobData, 2> {
- return { {
- {
- .segmentsCount = 6,
- .minScale = kBlobScale * kMinorBlobFactor,
- .minRadius = st::groupCallRowBlobMinRadius * kMinorBlobFactor,
- .maxRadius = st::groupCallRowBlobMaxRadius * kMinorBlobFactor,
- .speedScale = 1.,
- .alpha = .5,
- },
- {
- .segmentsCount = 8,
- .minScale = kBlobScale,
- .minRadius = (float)st::groupCallRowBlobMinRadius,
- .maxRadius = (float)st::groupCallRowBlobMaxRadius,
- .speedScale = 1.,
- .alpha = .2,
- },
- } };
- }
- [[nodiscard]] QString StatusPercentString(float volume) {
- return QString::number(int(base::SafeRound(volume * 200))) + '%';
- }
- [[nodiscard]] int StatusPercentWidth(const QString &percent) {
- return st::normalFont->width(percent);
- }
- } // namespace
- struct MembersRow::BlobsAnimation {
- BlobsAnimation(
- std::vector<Ui::Paint::Blobs::BlobData> blobDatas,
- float levelDuration,
- float maxLevel);
- Ui::Paint::Blobs blobs;
- crl::time lastTime = 0;
- crl::time lastSoundingUpdateTime = 0;
- float64 enter = 0.;
- QImage userpicCache;
- InMemoryKey userpicKey;
- rpl::lifetime lifetime;
- };
- struct MembersRow::StatusIcon {
- StatusIcon(bool shown, float volume);
- const style::icon &speaker;
- Ui::Paint::ArcsAnimation arcs;
- Ui::Animations::Simple arcsAnimation;
- Ui::Animations::Simple shownAnimation;
- QString percent;
- int percentWidth = 0;
- int arcsWidth = 0;
- int wasArcsWidth = 0;
- bool shown = true;
- rpl::lifetime lifetime;
- };
- MembersRow::BlobsAnimation::BlobsAnimation(
- std::vector<Ui::Paint::Blobs::BlobData> blobDatas,
- float levelDuration,
- float maxLevel)
- : blobs(std::move(blobDatas), levelDuration, maxLevel) {
- style::PaletteChanged(
- ) | rpl::start_with_next([=] {
- userpicCache = QImage();
- }, lifetime);
- }
- MembersRow::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) {
- }
- MembersRow::MembersRow(
- not_null<MembersRowDelegate*> delegate,
- not_null<PeerData*> participantPeer)
- : PeerListRow(participantPeer)
- , _delegate(delegate) {
- refreshStatus();
- _about.setText(st::defaultTextStyle, participantPeer->about());
- }
- MembersRow::~MembersRow() = default;
- void MembersRow::setSkipLevelUpdate(bool value) {
- _skipLevelUpdate = value;
- }
- void MembersRow::updateState(
- const Data::GroupCallParticipant *participant) {
- setVolume(participant
- ? participant->volume
- : Group::kDefaultVolume);
- if (!participant) {
- setState(State::Invited);
- setSounding(false);
- setSpeaking(false);
- _mutedByMe = false;
- _raisedHandRating = 0;
- } else if (!participant->muted
- || (participant->sounding && participant->ssrc != 0)
- || (participant->additionalSounding
- && GetAdditionalAudioSsrc(participant->videoParams) != 0)) {
- setState(State::Active);
- setSounding((participant->sounding && participant->ssrc != 0)
- || (participant->additionalSounding
- && GetAdditionalAudioSsrc(participant->videoParams) != 0));
- setSpeaking((participant->speaking && participant->ssrc != 0)
- || (participant->additionalSpeaking
- && GetAdditionalAudioSsrc(participant->videoParams) != 0));
- _mutedByMe = participant->mutedByMe;
- _raisedHandRating = 0;
- } else if (participant->canSelfUnmute) {
- setState(State::Inactive);
- setSounding(false);
- setSpeaking(false);
- _mutedByMe = participant->mutedByMe;
- _raisedHandRating = 0;
- } else {
- setSounding(false);
- setSpeaking(false);
- _mutedByMe = participant->mutedByMe;
- _raisedHandRating = participant->raisedHandRating;
- setState(_raisedHandRating ? State::RaisedHand : State::Muted);
- }
- refreshStatus();
- }
- void MembersRow::setSpeaking(bool speaking) {
- if (_speaking == speaking) {
- return;
- }
- _speaking = speaking;
- _speakingAnimation.start(
- [=] { _delegate->rowUpdateRow(this); },
- _speaking ? 0. : 1.,
- _speaking ? 1. : 0.,
- st::widgetFadeDuration);
- if (!_speaking
- || _mutedByMe
- || (_state == State::Muted)
- || (_state == State::RaisedHand)) {
- if (_statusIcon) {
- _statusIcon = nullptr;
- _delegate->rowUpdateRow(this);
- }
- } else if (!_statusIcon) {
- _statusIcon = std::make_unique<StatusIcon>(
- (_volume != Group::kDefaultVolume),
- (float)_volume / Group::kMaxVolume);
- _statusIcon->arcs.setStrokeRatio(kArcsStrokeRatio);
- _statusIcon->arcsWidth = _statusIcon->arcs.finishedWidth();
- _statusIcon->arcs.startUpdateRequests(
- ) | rpl::start_with_next([=] {
- if (!_statusIcon->arcsAnimation.animating()) {
- _statusIcon->wasArcsWidth = _statusIcon->arcsWidth;
- }
- auto callback = [=](float64 value) {
- _statusIcon->arcs.update(crl::now());
- _statusIcon->arcsWidth = anim::interpolate(
- _statusIcon->wasArcsWidth,
- _statusIcon->arcs.finishedWidth(),
- value);
- _delegate->rowUpdateRow(this);
- };
- _statusIcon->arcsAnimation.start(
- std::move(callback),
- 0.,
- 1.,
- st::groupCallSpeakerArcsAnimation.duration);
- }, _statusIcon->lifetime);
- }
- }
- void MembersRow::setSounding(bool sounding) {
- if (_sounding == sounding) {
- return;
- }
- _sounding = sounding;
- if (!_sounding) {
- _blobsAnimation = nullptr;
- } else if (!_blobsAnimation) {
- _blobsAnimation = std::make_unique<BlobsAnimation>(
- RowBlobs() | ranges::to_vector,
- kLevelDuration,
- kMaxLevel);
- _blobsAnimation->lastTime = crl::now();
- updateLevel(GroupCall::kSpeakLevelThreshold);
- }
- }
- void MembersRow::clearRaisedHandStatus() {
- if (!_raisedHandStatus) {
- return;
- }
- _raisedHandStatus = false;
- refreshStatus();
- _delegate->rowUpdateRow(this);
- }
- void MembersRow::setState(State state) {
- if (_state == state) {
- return;
- }
- const auto wasActive = (_state == State::Active);
- const auto wasMuted = (_state == State::Muted)
- || (_state == State::RaisedHand);
- const auto wasRaisedHand = (_state == State::RaisedHand);
- _state = state;
- const auto nowActive = (_state == State::Active);
- const auto nowMuted = (_state == State::Muted)
- || (_state == State::RaisedHand);
- const auto nowRaisedHand = (_state == State::RaisedHand);
- if (!wasRaisedHand && nowRaisedHand) {
- _raisedHandStatus = true;
- _delegate->rowScheduleRaisedHandStatusRemove(this);
- }
- if (nowActive != wasActive) {
- _activeAnimation.start(
- [=] { _delegate->rowUpdateRow(this); },
- nowActive ? 0. : 1.,
- nowActive ? 1. : 0.,
- st::widgetFadeDuration);
- }
- if (nowMuted != wasMuted) {
- _mutedAnimation.start(
- [=] { _delegate->rowUpdateRow(this); },
- nowMuted ? 0. : 1.,
- nowMuted ? 1. : 0.,
- st::widgetFadeDuration);
- }
- }
- void MembersRow::setVolume(int volume) {
- _volume = volume;
- if (_statusIcon) {
- 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);
- }
- }
- }
- void MembersRow::updateLevel(float level) {
- Expects(_blobsAnimation != nullptr);
- const auto spoke = (level >= GroupCall::kSpeakLevelThreshold)
- ? crl::now()
- : crl::time();
- if (spoke && _speaking) {
- _speakingLastTime = spoke;
- }
- if (_skipLevelUpdate) {
- return;
- }
- if (spoke) {
- _blobsAnimation->lastSoundingUpdateTime = spoke;
- }
- _blobsAnimation->blobs.setLevel(level);
- }
- void MembersRow::updateBlobAnimation(crl::time now) {
- Expects(_blobsAnimation != nullptr);
- const auto soundingFinishesAt = _blobsAnimation->lastSoundingUpdateTime
- + Data::GroupCall::kSoundStatusKeptFor;
- const auto soundingStartsFinishing = soundingFinishesAt
- - kBlobsEnterDuration;
- const auto soundingFinishes = (soundingStartsFinishing < now);
- if (soundingFinishes) {
- _blobsAnimation->enter = std::clamp(
- (soundingFinishesAt - now) / float64(kBlobsEnterDuration),
- 0.,
- 1.);
- } else if (_blobsAnimation->enter < 1.) {
- _blobsAnimation->enter = std::clamp(
- (_blobsAnimation->enter
- + ((now - _blobsAnimation->lastTime)
- / float64(kBlobsEnterDuration))),
- 0.,
- 1.);
- }
- _blobsAnimation->blobs.updateLevel(now - _blobsAnimation->lastTime);
- _blobsAnimation->lastTime = now;
- }
- void MembersRow::ensureUserpicCache(
- Ui::PeerUserpicView &view,
- int size) {
- Expects(_blobsAnimation != nullptr);
- const auto user = peer();
- const auto key = user->userpicUniqueKey(view);
- const auto full = QSize(size, size)
- * kWideScale
- * style::DevicePixelRatio();
- auto &cache = _blobsAnimation->userpicCache;
- if (cache.isNull()) {
- cache = QImage(full, QImage::Format_ARGB32_Premultiplied);
- cache.setDevicePixelRatio(style::DevicePixelRatio());
- } else if (_blobsAnimation->userpicKey == key
- && cache.size() == full) {
- return;
- }
- _blobsAnimation->userpicKey = key;
- cache.fill(Qt::transparent);
- {
- Painter p(&cache);
- const auto skip = (kWideScale - 1) / 2 * size;
- user->paintUserpicLeft(p, view, skip, skip, kWideScale * size, size);
- }
- }
- void MembersRow::paintBlobs(
- Painter &p,
- int x,
- int y,
- int sizew,
- int sizeh,
- PanelMode mode) {
- if (!_blobsAnimation) {
- return;
- }
- auto size = sizew;
- const auto shift = QPointF(x + size / 2., y + size / 2.);
- auto hq = PainterHighQualityEnabler(p);
- p.translate(shift);
- const auto brush = _mutedByMe
- ? st::groupCallMemberMutedIcon->b
- : anim::brush(
- st::groupCallMemberInactiveStatus,
- st::groupCallMemberActiveStatus,
- _speakingAnimation.value(_speaking ? 1. : 0.));
- _blobsAnimation->blobs.paint(p, brush);
- p.translate(-shift);
- p.setOpacity(1.);
- }
- void MembersRow::paintScaledUserpic(
- Painter &p,
- Ui::PeerUserpicView &userpic,
- int x,
- int y,
- int outerWidth,
- int sizew,
- int sizeh,
- PanelMode mode) {
- auto size = sizew;
- if (!_blobsAnimation) {
- peer()->paintUserpicLeft(p, userpic, x, y, outerWidth, size);
- return;
- }
- const auto enter = _blobsAnimation->enter;
- const auto &minScale = kUserpicMinScale;
- const auto scaleUserpic = minScale
- + (1. - minScale) * _blobsAnimation->blobs.currentLevel();
- const auto scale = scaleUserpic * enter + 1. * (1. - enter);
- if (scale == 1.) {
- peer()->paintUserpicLeft(p, userpic, x, y, outerWidth, size);
- return;
- }
- ensureUserpicCache(userpic, size);
- PainterHighQualityEnabler hq(p);
- auto target = QRect(
- x + (1 - kWideScale) / 2 * size,
- y + (1 - kWideScale) / 2 * size,
- kWideScale * size,
- kWideScale * size);
- auto shrink = anim::interpolate(
- (1 - kWideScale) / 2 * size,
- 0,
- scale);
- auto margins = QMargins(shrink, shrink, shrink, shrink);
- p.drawImage(
- target.marginsAdded(margins),
- _blobsAnimation->userpicCache);
- }
- void MembersRow::paintMuteIcon(
- QPainter &p,
- QRect iconRect,
- MembersRowStyle style) {
- _delegate->rowPaintIcon(p, iconRect, computeIconState(style));
- }
- auto MembersRow::generatePaintUserpicCallback(bool forceRound)
- -> PaintRoundImageCallback {
- return [=](Painter &p, int x, int y, int outerWidth, int size) {
- const auto outer = outerWidth;
- paintComplexUserpic(p, x, y, outer, size, size, PanelMode::Default);
- };
- }
- void MembersRow::paintComplexUserpic(
- Painter &p,
- int x,
- int y,
- int outerWidth,
- int sizew,
- int sizeh,
- PanelMode mode,
- bool selected) {
- paintBlobs(p, x, y, sizew, sizeh, mode);
- paintScaledUserpic(
- p,
- ensureUserpicView(),
- x,
- y,
- outerWidth,
- sizew,
- sizeh,
- mode);
- }
- int MembersRow::statusIconWidth(bool skipIcon) const {
- if (!_statusIcon || !_speaking) {
- return 0;
- }
- const auto shown = _statusIcon->shownAnimation.value(
- _statusIcon->shown ? 1. : 0.);
- const auto iconWidth = skipIcon
- ? 0
- : (_statusIcon->speaker.width() + _statusIcon->arcsWidth);
- const auto full = iconWidth
- + _statusIcon->percentWidth
- + st::normalFont->spacew;
- return int(base::SafeRound(shown * full));
- }
- int MembersRow::statusIconHeight() const {
- return (_statusIcon && _speaking) ? _statusIcon->speaker.height() : 0;
- }
- void MembersRow::paintStatusIcon(
- Painter &p,
- int x,
- int y,
- const style::PeerListItem &st,
- const style::font &font,
- bool selected,
- bool skipIcon) {
- if (!_statusIcon) {
- return;
- }
- const auto shown = _statusIcon->shownAnimation.value(
- _statusIcon->shown ? 1. : 0.);
- if (shown == 0.) {
- return;
- }
- p.setFont(font);
- const auto color = (_speaking
- ? st.statusFgActive
- : (selected ? st.statusFgOver : st.statusFg))->c;
- p.setPen(color);
- const auto speakerRect = QRect(
- QPoint(x, y + (font->height - statusIconHeight()) / 2),
- _statusIcon->speaker.size());
- const auto arcPosition = speakerRect.topLeft()
- + QPoint(
- speakerRect.width() - st::groupCallStatusSpeakerArcsSkip,
- speakerRect.height() / 2);
- const auto iconWidth = skipIcon
- ? 0
- : (speakerRect.width() + _statusIcon->arcsWidth);
- const auto fullWidth = iconWidth
- + _statusIcon->percentWidth
- + st::normalFont->spacew;
- 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);
- }
- if (!skipIcon) {
- _statusIcon->speaker.paint(
- p,
- speakerRect.topLeft(),
- speakerRect.width(),
- color);
- p.translate(arcPosition);
- _statusIcon->arcs.paint(p, color);
- p.translate(-arcPosition);
- }
- p.setFont(st::normalFont);
- p.setPen(st.statusFgActive);
- p.drawTextLeft(
- x + iconWidth,
- y,
- fullWidth,
- _statusIcon->percent);
- p.restore();
- }
- void MembersRow::setAbout(const QString &about) {
- if (_about.toString() == about) {
- return;
- }
- _about.setText(st::defaultTextStyle, about);
- _delegate->rowUpdateRow(this);
- }
- void MembersRow::paintStatusText(
- Painter &p,
- const style::PeerListItem &st,
- int x,
- int y,
- int availableWidth,
- int outerWidth,
- bool selected) {
- paintComplexStatusText(
- p,
- st,
- x,
- y,
- availableWidth,
- outerWidth,
- selected,
- MembersRowStyle::Default);
- }
- void MembersRow::paintComplexStatusText(
- Painter &p,
- const style::PeerListItem &st,
- int x,
- int y,
- int availableWidth,
- int outerWidth,
- bool selected,
- MembersRowStyle style) {
- const auto skip = (style == MembersRowStyle::Default)
- ? _delegate->rowPaintStatusIcon(
- p,
- x,
- y,
- outerWidth,
- this,
- computeIconState(MembersRowStyle::Narrow))
- : 0;
- const auto narrowMode = (skip > 0);
- x += skip;
- availableWidth -= skip;
- const auto &font = st::normalFont;
- const auto useAbout = !_about.isEmpty()
- && (style != MembersRowStyle::Video)
- && ((_state == State::RaisedHand && !_raisedHandStatus)
- || (_state != State::RaisedHand && !_speaking));
- if (!useAbout
- && _state != State::Invited
- && !_mutedByMe) {
- paintStatusIcon(p, x, y, st, font, selected, narrowMode);
- const auto translatedWidth = statusIconWidth(narrowMode);
- p.translate(translatedWidth, 0);
- const auto guard = gsl::finally([&] {
- p.translate(-translatedWidth, 0);
- });
- const auto &style = (!narrowMode
- || (_state == State::RaisedHand && _raisedHandStatus))
- ? st
- : st::groupCallNarrowMembersListItem;
- PeerListRow::paintStatusText(
- p,
- style,
- x,
- y,
- availableWidth - translatedWidth,
- outerWidth,
- selected);
- return;
- }
- p.setPen((style == MembersRowStyle::Video)
- ? st::groupCallVideoSubTextFg
- : _mutedByMe
- ? st::groupCallMemberMutedIcon
- : st::groupCallMemberNotJoinedStatus);
- if (!_mutedByMe && useAbout) {
- return _about.draw(p, {
- .position = QPoint(x, y),
- .outerWidth = outerWidth,
- .availableWidth = availableWidth,
- .elisionLines = 1,
- });
- } else {
- p.setFont(font);
- p.drawTextLeft(
- x,
- y,
- outerWidth,
- (_mutedByMe
- ? tr::lng_group_call_muted_by_me_status(tr::now)
- : _delegate->rowIsMe(peer())
- ? tr::lng_status_connecting(tr::now)
- : tr::lng_group_call_invited_status(tr::now)));
- }
- }
- QSize MembersRow::rightActionSize() const {
- return _delegate->rowIsNarrow() ? QSize() : QSize(
- st::groupCallActiveButton.width,
- st::groupCallActiveButton.height);
- }
- bool MembersRow::rightActionDisabled() const {
- return _delegate->rowIsMe(peer())
- || (_state == State::Invited)
- || !_delegate->rowCanMuteMembers();
- }
- QMargins MembersRow::rightActionMargins() const {
- return QMargins(
- 0,
- 0,
- st::groupCallMemberButtonSkip,
- 0);
- }
- void MembersRow::rightActionPaint(
- Painter &p,
- int x,
- int y,
- int outerWidth,
- bool selected,
- bool actionSelected) {
- auto size = rightActionSize();
- const auto iconRect = style::rtlrect(
- x,
- y,
- size.width(),
- size.height(),
- outerWidth);
- if (_state == State::Invited) {
- _actionRipple = nullptr;
- }
- if (_actionRipple) {
- _actionRipple->paint(
- p,
- x + st::groupCallActiveButton.rippleAreaPosition.x(),
- y + st::groupCallActiveButton.rippleAreaPosition.y(),
- outerWidth);
- if (_actionRipple->empty()) {
- _actionRipple.reset();
- }
- }
- paintMuteIcon(p, iconRect);
- }
- MembersRowDelegate::IconState MembersRow::computeIconState(
- MembersRowStyle style) const {
- const auto speaking = _speakingAnimation.value(_speaking ? 1. : 0.);
- const auto active = _activeAnimation.value(
- (_state == State::Active) ? 1. : 0.);
- const auto muted = _mutedAnimation.value(
- (_state == State::Muted || _state == State::RaisedHand) ? 1. : 0.);
- return {
- .speaking = speaking,
- .active = active,
- .muted = muted,
- .mutedByMe = _mutedByMe,
- .raisedHand = (_state == State::RaisedHand),
- .invited = (_state == State::Invited),
- .style = style,
- };
- }
- void MembersRow::showContextMenu() {
- return _delegate->rowShowContextMenu(this);
- }
- void MembersRow::refreshStatus() {
- setCustomStatus(
- (_speaking
- ? tr::lng_group_call_active(tr::now)
- : _raisedHandStatus
- ? tr::lng_group_call_raised_hand_status(tr::now)
- : tr::lng_group_call_inactive(tr::now)),
- _speaking);
- }
- void MembersRow::rightActionAddRipple(
- QPoint point,
- Fn<void()> updateCallback) {
- if (!_actionRipple) {
- auto mask = Ui::RippleAnimation::EllipseMask(QSize(
- st::groupCallActiveButton.rippleAreaSize,
- st::groupCallActiveButton.rippleAreaSize));
- _actionRipple = std::make_unique<Ui::RippleAnimation>(
- st::groupCallActiveButton.ripple,
- std::move(mask),
- std::move(updateCallback));
- }
- _actionRipple->add(point - st::groupCallActiveButton.rippleAreaPosition);
- }
- void MembersRow::refreshName(const style::PeerListItem &st) {
- PeerListRow::refreshName(st);
- //_narrowName = Ui::Text::String();
- }
- void MembersRow::rightActionStopLastRipple() {
- if (_actionRipple) {
- _actionRipple->lastStop();
- }
- }
- } // namespace Calls::Group
|