Added last seen button and rating to status in profile top bar.

This commit is contained in:
23rd
2025-10-08 19:12:45 +03:00
parent d26cda097f
commit d59ab17ac5
3 changed files with 144 additions and 1 deletions
+1
View File
@@ -252,6 +252,7 @@ infoLayerProfileTopBarTitleTop: 150px;
infoLayerProfileTopBarStatusTop: 170px;
infoLayerProfileTopBarPhotoTop: 30px;
infoLayerProfileTopBarPhotoSize: 104px;
infoLayerProfileTopBarLastSeenSkip: 8px;
infoLayerTopMinimal: 20px;
infoLayerTopMaximal: 40px;
@@ -7,10 +7,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "info/profile/info_profile_top_bar.h"
#include "api/api_user_privacy.h"
#include "apiwrap.h"
#include "base/unixtime.h"
#include "calls/calls_instance.h"
#include "core/application.h"
#include "core/shortcuts.h"
#include "data/data_changes.h"
#include "data/data_peer_values.h"
#include "data/data_peer.h"
#include "data/data_session.h"
#include "data/data_user.h"
@@ -19,11 +23,17 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "info/info_memento.h"
#include "info/profile/info_profile_status_label.h"
#include "info/profile/info_profile_values.h"
#include "lang/lang_keys.h"
#include "main/main_session.h"
#include "settings/settings_premium.h"
#include "ui/boxes/show_or_premium_box.h"
#include "ui/controls/stars_rating.h"
#include "ui/effects/animations.h"
#include "ui/layers/generic_box.h"
#include "ui/painter.h"
#include "ui/rect.h"
#include "ui/widgets/buttons.h"
#include "ui/widgets/buttons.h"
#include "ui/widgets/labels.h"
#include "ui/widgets/menu/menu_add_action_callback_factory.h"
#include "ui/widgets/popup_menu.h"
@@ -36,6 +46,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "styles/style_layers.h"
#include "styles/style_settings.h"
#include <QGraphicsOpacityEffect>
namespace Info::Profile {
TopBar::TopBar(
@@ -45,12 +57,39 @@ TopBar::TopBar(
, _peer(descriptor.controller->key().peer())
, _st(st::infoTopBar)
, _title(this, Info::Profile::NameValue(_peer), _st.title)
, _starsRating(_peer->isUser()
? std::make_unique<Ui::StarsRating>(
this,
descriptor.controller->uiShow(),
_peer->isSelf() ? QString() : _peer->shortName(),
Data::StarsRatingValue(_peer),
(_peer->isSelf()
? [=] { return _peer->owner().pendingStarsRating(); }
: Fn<Data::StarsRatingPending()>()))
: nullptr)
, _status(this, QString(), _st.subtitle)
, _statusLabel(
std::make_unique<StatusLabel>(_status.data(), _peer, rpl::single(0))) {
std::make_unique<StatusLabel>(_status.data(), _peer, rpl::single(0)))
, _showLastSeen(
this,
tr::lng_status_lastseen_when(),
st::infoProfileCover.showLastSeen) {
QWidget::setMinimumHeight(st::infoLayerTopBarHeight);
QWidget::setMaximumHeight(st::infoLayerProfileTopBarHeightMax);
if (!_peer->isMegagroup()) {
_status->setAttribute(Qt::WA_TransparentForMouseEvents);
if (const auto rating = _starsRating.get()) {
_statusShift = rating->widthValue();
_statusShift.changes() | rpl::start_with_next([=] {
updateLabelsPosition();
}, _status->lifetime());
rating->raise();
}
}
setupShowLastSeen(descriptor.controller);
_peer->session().changes().peerFlagsValue(
_peer,
Data::PeerUpdate::Flag::OnlineStatus
@@ -150,8 +189,27 @@ void TopBar::updateLabelsPosition() {
(width() - _status->width()) / 2,
progressCurrent);
if (const auto rating = _starsRating.get()) {
rating->moveTo(statusLeft - _statusShift.current(), statusTop);
rating->setOpacity(progressCurrent);
}
_title->moveToLeft(titleLeft, titleTop);
_status->moveToLeft(statusLeft, statusTop);
if (!_showLastSeen->isHidden()) {
_showLastSeen->moveToLeft(
statusLeft
+ _status->textMaxWidth()
+ st::infoLayerProfileTopBarLastSeenSkip,
statusTop);
if (_showLastSeenOpacity) {
_showLastSeenOpacity->setOpacity(progressCurrent);
}
_showLastSeen->setAttribute(
Qt::WA_TransparentForMouseEvents,
!progressCurrent);
}
}
void TopBar::resizeEvent(QResizeEvent *e) {
@@ -376,4 +434,79 @@ void TopBar::addProfileCallsButton(
}
}
void TopBar::setupShowLastSeen(not_null<Controller*> controller) {
const auto user = _peer->asUser();
if (!user
|| user->isSelf()
|| user->isBot()
|| user->isServiceUser()
|| !user->session().premiumPossible()) {
_showLastSeen->hide();
return;
}
if (user->session().premium()) {
if (user->lastseen().isHiddenByMe()) {
user->updateFullForced();
}
_showLastSeen->hide();
return;
}
rpl::combine(
user->session().changes().peerFlagsValue(
user,
Data::PeerUpdate::Flag::OnlineStatus),
Data::AmPremiumValue(&user->session())
) | rpl::start_with_next([=](auto, bool premium) {
const auto wasShown = !_showLastSeen->isHidden();
const auto hiddenByMe = user->lastseen().isHiddenByMe();
const auto shown = hiddenByMe
&& !user->lastseen().isOnline(base::unixtime::now())
&& !premium
&& user->session().premiumPossible();
_showLastSeen->setVisible(shown);
if (wasShown && premium && hiddenByMe) {
user->updateFullForced();
}
}, _showLastSeen->lifetime());
controller->session().api().userPrivacy().value(
Api::UserPrivacy::Key::LastSeen
) | rpl::filter([=](Api::UserPrivacy::Rule rule) {
return (rule.option == Api::UserPrivacy::Option::Everyone);
}) | rpl::start_with_next([=] {
if (user->lastseen().isHiddenByMe()) {
user->updateFullForced();
}
}, _showLastSeen->lifetime());
_showLastSeenOpacity = Ui::CreateChild<QGraphicsOpacityEffect>(
_showLastSeen.get());
_showLastSeen->setGraphicsEffect(_showLastSeenOpacity);
_showLastSeenOpacity->setOpacity(0.);
using TextTransform = Ui::RoundButton::TextTransform;
_showLastSeen->setTextTransform(TextTransform::NoTransform);
_showLastSeen->setFullRadius(true);
_showLastSeen->setClickedCallback([=] {
const auto type = Ui::ShowOrPremium::LastSeen;
controller->parentController()->show(Box(
Ui::ShowOrPremiumBox,
type,
user->shortName(),
[=] {
controller->session().api().userPrivacy().save(
::Api::UserPrivacy::Key::LastSeen,
{});
},
[=] {
::Settings::ShowPremium(
controller->parentController(),
u"lastseen_hidden"_q);
}));
});
}
} // namespace Info::Profile
@@ -17,10 +17,14 @@ namespace style {
struct InfoTopBar;
} //namespace style
class QGraphicsOpacityEffect;
namespace Ui {
class FlatLabel;
class IconButton;
class PopupMenu;
class RoundButton;
class StarsRating;
template <typename Widget>
class FadeWrap;
} //namespace Ui
@@ -71,13 +75,18 @@ private:
void setupButtons(
not_null<Controller*> controller,
rpl::producer<bool> backToggles);
void setupShowLastSeen(not_null<Controller*> controller);
const not_null<PeerData*> _peer;
const style::InfoTopBar &_st;
object_ptr<Ui::FlatLabel> _title;
std::unique_ptr<Ui::StarsRating> _starsRating;
object_ptr<Ui::FlatLabel> _status;
std::unique_ptr<StatusLabel> _statusLabel;
rpl::variable<int> _statusShift = 0;
object_ptr<Ui::RoundButton> _showLastSeen = { nullptr };
QGraphicsOpacityEffect *_showLastSeenOpacity = nullptr;
rpl::variable<int> _onlineCount = 0;
rpl::variable<float64> _progress = 0.;