mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-15 21:57:10 +02:00
Implement channel stories views / reactions.
This commit is contained in:
parent
1c2951598b
commit
f3db7e636b
15 changed files with 247 additions and 53 deletions
BIN
Telegram/Resources/icons/mediaview/views.png
Normal file
BIN
Telegram/Resources/icons/mediaview/views.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 476 B |
BIN
Telegram/Resources/icons/mediaview/views@2x.png
Normal file
BIN
Telegram/Resources/icons/mediaview/views@2x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 884 B |
BIN
Telegram/Resources/icons/mediaview/views@3x.png
Normal file
BIN
Telegram/Resources/icons/mediaview/views@3x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
|
@ -221,14 +221,14 @@ struct StoryUpdate {
|
|||
enum class Flag : uint32 {
|
||||
None = 0,
|
||||
|
||||
Edited = (1U << 0),
|
||||
Destroyed = (1U << 1),
|
||||
NewAdded = (1U << 2),
|
||||
ViewsAdded = (1U << 3),
|
||||
MarkRead = (1U << 4),
|
||||
Reaction = (1U << 5),
|
||||
Edited = (1U << 0),
|
||||
Destroyed = (1U << 1),
|
||||
NewAdded = (1U << 2),
|
||||
ViewsChanged = (1U << 3),
|
||||
MarkRead = (1U << 4),
|
||||
Reaction = (1U << 5),
|
||||
|
||||
LastUsedBit = (1U << 5),
|
||||
LastUsedBit = (1U << 5),
|
||||
};
|
||||
using Flags = base::flags<Flag>;
|
||||
friend inline constexpr auto is_flag_type(Flag) { return true; }
|
||||
|
|
|
@ -410,8 +410,17 @@ Data::ReactionId Story::sentReactionId() const {
|
|||
|
||||
void Story::setReactionId(Data::ReactionId id) {
|
||||
if (_sentReactionId != id) {
|
||||
const auto wasEmpty = _sentReactionId.empty();
|
||||
_sentReactionId = id;
|
||||
session().changes().storyUpdated(this, UpdateFlag::Reaction);
|
||||
auto flags = UpdateFlag::Reaction | UpdateFlag();
|
||||
if (_views.known && _sentReactionId.empty() != wasEmpty) {
|
||||
const auto delta = wasEmpty ? 1 : -1;
|
||||
if (_views.reactions + delta >= 0) {
|
||||
_views.reactions += delta;
|
||||
flags |= UpdateFlag::ViewsChanged;
|
||||
}
|
||||
}
|
||||
session().changes().storyUpdated(this, flags);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -438,6 +447,7 @@ void Story::applyViewsSlice(
|
|||
|| (_views.total != slice.total);
|
||||
_views.reactions = slice.reactions;
|
||||
_views.total = slice.total;
|
||||
_views.known = true;
|
||||
if (offset.isEmpty()) {
|
||||
_views = slice;
|
||||
} else if (_views.nextOffset == offset) {
|
||||
|
@ -468,14 +478,14 @@ void Story::applyViewsSlice(
|
|||
// Count not changed, but list of recent viewers changed.
|
||||
_peer->session().changes().storyUpdated(
|
||||
this,
|
||||
UpdateFlag::ViewsAdded);
|
||||
UpdateFlag::ViewsChanged);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (changed) {
|
||||
_peer->session().changes().storyUpdated(
|
||||
this,
|
||||
UpdateFlag::ViewsAdded);
|
||||
UpdateFlag::ViewsChanged);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -528,9 +538,11 @@ void Story::applyFields(
|
|||
auto views = _views.total;
|
||||
auto reactions = _views.reactions;
|
||||
auto viewers = std::vector<not_null<PeerData*>>();
|
||||
auto viewsKnown = _views.known;
|
||||
if (const auto info = data.vviews()) {
|
||||
views = info->data().vviews_count().v;
|
||||
reactions = info->data().vreactions_count().value_or_empty();
|
||||
viewsKnown = true;
|
||||
if (const auto list = info->data().vrecent_viewers()) {
|
||||
viewers.reserve(list->v.size());
|
||||
auto &owner = _peer->owner();
|
||||
|
@ -577,8 +589,14 @@ void Story::applyFields(
|
|||
_edited = edited;
|
||||
_pinned = pinned;
|
||||
_noForwards = noForwards;
|
||||
if (_views.reactions != reactions || _views.total != views) {
|
||||
_views = StoryViews{ .reactions = reactions, .total = views };
|
||||
if (_views.reactions != reactions
|
||||
|| _views.total != views
|
||||
|| _views.known != viewsKnown) {
|
||||
_views = StoryViews{
|
||||
.reactions = reactions,
|
||||
.total = views,
|
||||
.known = viewsKnown,
|
||||
};
|
||||
}
|
||||
if (viewsChanged) {
|
||||
_recentViewers = std::move(viewers);
|
||||
|
@ -607,7 +625,7 @@ void Story::applyFields(
|
|||
if (!initial && (changed || viewsChanged || reactionChanged)) {
|
||||
_peer->session().changes().storyUpdated(this, UpdateFlag()
|
||||
| (changed ? UpdateFlag::Edited : UpdateFlag())
|
||||
| (viewsChanged ? UpdateFlag::ViewsAdded : UpdateFlag())
|
||||
| (viewsChanged ? UpdateFlag::ViewsChanged : UpdateFlag())
|
||||
| (reactionChanged ? UpdateFlag::Reaction : UpdateFlag()));
|
||||
}
|
||||
if (!initial && (captionChanged || mediaChanged)) {
|
||||
|
|
|
@ -71,6 +71,7 @@ struct StoryViews {
|
|||
QString nextOffset;
|
||||
int reactions = 0;
|
||||
int total = 0;
|
||||
bool known = false;
|
||||
};
|
||||
|
||||
struct StoryArea {
|
||||
|
|
|
@ -937,6 +937,10 @@ ShortenedCount FormatCountToShort(int64 number) {
|
|||
return result;
|
||||
}
|
||||
|
||||
QString FormatCountDecimal(int64 number) {
|
||||
return QString("%L1").arg(number);
|
||||
}
|
||||
|
||||
PluralResult Plural(
|
||||
ushort keyBase,
|
||||
float64 value,
|
||||
|
@ -973,7 +977,7 @@ PluralResult Plural(
|
|||
if (type == lt_count_short) {
|
||||
return { shift, shortened.string };
|
||||
} else if (type == lt_count_decimal) {
|
||||
return { shift, QString("%L1").arg(round) };
|
||||
return { shift, FormatCountDecimal(round) };
|
||||
}
|
||||
return { shift, QString::number(round) };
|
||||
}
|
||||
|
|
|
@ -14,13 +14,16 @@ namespace Lang {
|
|||
inline constexpr auto kTextCommandLangTag = 0x20;
|
||||
constexpr auto kTagReplacementSize = 4;
|
||||
|
||||
int FindTagReplacementPosition(const QString &original, ushort tag);
|
||||
[[nodiscard]] int FindTagReplacementPosition(
|
||||
const QString &original,
|
||||
ushort tag);
|
||||
|
||||
struct ShortenedCount {
|
||||
int64 number = 0;
|
||||
QString string;
|
||||
};
|
||||
ShortenedCount FormatCountToShort(int64 number);
|
||||
[[nodiscard]] ShortenedCount FormatCountToShort(int64 number);
|
||||
[[nodiscard]] QString FormatCountDecimal(int64 number);
|
||||
|
||||
struct PluralResult {
|
||||
int keyShift = 0;
|
||||
|
|
|
@ -855,24 +855,32 @@ void Controller::show(
|
|||
if (!changeShown(story)) {
|
||||
return;
|
||||
}
|
||||
_viewed = false;
|
||||
invalidate_weak_ptrs(&_viewsLoadGuard);
|
||||
_reactions->hide();
|
||||
if (_replyArea->focused()) {
|
||||
unfocusReply();
|
||||
}
|
||||
|
||||
_replyArea->show({
|
||||
.peer = unsupported ? nullptr : peer.get(),
|
||||
.id = story->id(),
|
||||
}, _reactions->likedValue());
|
||||
|
||||
const auto wasLikeButton = QPointer(_recentViews->likeButton());
|
||||
_recentViews->show({
|
||||
.list = story->recentViewers(),
|
||||
.reactions = story->reactions(),
|
||||
.total = story->views(),
|
||||
.valid = peer->isSelf(),
|
||||
});
|
||||
.self = peer->isSelf(),
|
||||
.channel = peer->isChannel(),
|
||||
}, _reactions->likedValue());
|
||||
if (const auto nowLikeButton = _recentViews->likeButton()) {
|
||||
if (wasLikeButton != nowLikeButton) {
|
||||
_reactions->attachToReactionButton(nowLikeButton);
|
||||
}
|
||||
}
|
||||
|
||||
if (peer->isSelf() || peer->isChannel()) {
|
||||
_reactions->setReactionIconWidget(_recentViews->likeIconWidget());
|
||||
} else if (const auto like = _replyArea->likeAnimationTarget()) {
|
||||
_reactions->setReactionIconWidget(like);
|
||||
}
|
||||
_reactions->showLikeFrom(story);
|
||||
|
||||
stories.loadAround(storyId, context);
|
||||
|
||||
|
@ -906,7 +914,6 @@ bool Controller::changeShown(Data::Story *story) {
|
|||
story,
|
||||
Data::Stories::Polling::Viewer);
|
||||
}
|
||||
_reactions->showLikeFrom(story);
|
||||
|
||||
const auto &locations = story
|
||||
? story->locations()
|
||||
|
@ -923,6 +930,14 @@ bool Controller::changeShown(Data::Story *story) {
|
|||
_areas.clear();
|
||||
}
|
||||
|
||||
_viewed = false;
|
||||
invalidate_weak_ptrs(&_viewsLoadGuard);
|
||||
_reactions->hide();
|
||||
_reactions->setReactionIconWidget(nullptr);
|
||||
if (_replyArea->focused()) {
|
||||
unfocusReply();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -947,7 +962,7 @@ void Controller::subscribeToSession() {
|
|||
}, _sessionLifetime);
|
||||
_session->changes().storyUpdates(
|
||||
Data::StoryUpdate::Flag::Edited
|
||||
| Data::StoryUpdate::Flag::ViewsAdded
|
||||
| Data::StoryUpdate::Flag::ViewsChanged
|
||||
) | rpl::filter([=](const Data::StoryUpdate &update) {
|
||||
return (update.story == this->story());
|
||||
}) | rpl::start_with_next([=](const Data::StoryUpdate &update) {
|
||||
|
@ -959,7 +974,8 @@ void Controller::subscribeToSession() {
|
|||
.list = update.story->recentViewers(),
|
||||
.reactions = update.story->reactions(),
|
||||
.total = update.story->views(),
|
||||
.valid = update.story->peer()->isSelf(),
|
||||
.self = update.story->peer()->isSelf(),
|
||||
.channel = update.story->peer()->isChannel(),
|
||||
});
|
||||
}
|
||||
}, _sessionLifetime);
|
||||
|
|
|
@ -445,7 +445,8 @@ void Reactions::Panel::collapse(Mode mode) {
|
|||
}
|
||||
}
|
||||
|
||||
void Reactions::Panel::attachToReactionButton(not_null<Ui::RpWidget*> button) {
|
||||
void Reactions::Panel::attachToReactionButton(
|
||||
not_null<Ui::RpWidget*> button) {
|
||||
base::install_event_filter(button, [=](not_null<QEvent*> e) {
|
||||
if (e->type() == QEvent::ContextMenu && !button->isHidden()) {
|
||||
show(Reactions::Mode::Reaction);
|
||||
|
@ -662,10 +663,17 @@ void Reactions::setReplyFieldState(
|
|||
}
|
||||
|
||||
void Reactions::attachToReactionButton(not_null<Ui::RpWidget*> button) {
|
||||
_likeButton = button;
|
||||
_panel->attachToReactionButton(button);
|
||||
}
|
||||
|
||||
void Reactions::setReactionIconWidget(Ui::RpWidget *widget) {
|
||||
if (_likeIconWidget != widget) {
|
||||
assignLikedId({});
|
||||
_likeIconWidget = widget;
|
||||
_reactionAnimation = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
auto Reactions::attachToMenu(
|
||||
not_null<Ui::PopupMenu*> menu,
|
||||
QPoint desiredPosition)
|
||||
|
@ -751,7 +759,7 @@ void Reactions::ready() {
|
|||
void Reactions::animateAndProcess(Chosen &&chosen) {
|
||||
const auto like = (chosen.mode == Mode::Reaction);
|
||||
const auto wrap = _controller->wrap();
|
||||
const auto target = like ? _likeButton : wrap.get();
|
||||
const auto target = like ? _likeIconWidget : wrap.get();
|
||||
const auto story = _controller->story();
|
||||
if (!story || !target) {
|
||||
return;
|
||||
|
@ -796,7 +804,7 @@ Fn<void(Ui::ReactionFlyCenter)> Reactions::setLikedIdIconInit(
|
|||
return nullptr;
|
||||
}
|
||||
assignLikedId(id);
|
||||
if (id.empty() || !_likeButton) {
|
||||
if (id.empty() || !_likeIconWidget) {
|
||||
return nullptr;
|
||||
}
|
||||
return crl::guard(&_likeIconGuard, [=](Ui::ReactionFlyCenter center) {
|
||||
|
@ -812,12 +820,12 @@ void Reactions::initLikeIcon(
|
|||
not_null<Data::Session*> owner,
|
||||
Data::ReactionId id,
|
||||
Ui::ReactionFlyCenter center) {
|
||||
Expects(_likeButton != nullptr);
|
||||
Expects(_likeIconWidget != nullptr);
|
||||
|
||||
_likeIcon = std::make_unique<Ui::RpWidget>(_likeButton);
|
||||
_likeIcon = std::make_unique<Ui::RpWidget>(_likeIconWidget);
|
||||
const auto icon = _likeIcon.get();
|
||||
icon->show();
|
||||
_likeButton->sizeValue() | rpl::start_with_next([=](QSize size) {
|
||||
_likeIconWidget->sizeValue() | rpl::start_with_next([=](QSize size) {
|
||||
icon->setGeometry(QRect(QPoint(), size));
|
||||
}, icon->lifetime());
|
||||
|
||||
|
|
|
@ -83,6 +83,7 @@ public:
|
|||
rpl::producer<bool> focused,
|
||||
rpl::producer<bool> hasSendText);
|
||||
void attachToReactionButton(not_null<Ui::RpWidget*> button);
|
||||
void setReactionIconWidget(Ui::RpWidget *widget);
|
||||
|
||||
using AttachStripResult = HistoryView::Reactions::AttachSelectorResult;
|
||||
[[nodiscard]] AttachStripResult attachToMenu(
|
||||
|
@ -123,7 +124,7 @@ private:
|
|||
bool _replyFocused = false;
|
||||
bool _hasSendText = false;
|
||||
|
||||
Ui::RpWidget *_likeButton = nullptr;
|
||||
Ui::RpWidget *_likeIconWidget = nullptr;
|
||||
rpl::variable<Data::ReactionId> _liked;
|
||||
base::has_weak_ptr _likeIconGuard;
|
||||
std::unique_ptr<Ui::RpWidget> _likeIcon;
|
||||
|
|
|
@ -18,6 +18,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/chat/group_call_userpics.h"
|
||||
#include "ui/controls/who_reacted_context_action.h"
|
||||
#include "ui/layers/box_content.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/popup_menu.h"
|
||||
#include "ui/painter.h"
|
||||
#include "ui/rp_widget.h"
|
||||
|
@ -128,7 +129,24 @@ RecentViews::RecentViews(not_null<Controller*> controller)
|
|||
|
||||
RecentViews::~RecentViews() = default;
|
||||
|
||||
void RecentViews::show(RecentViewsData data) {
|
||||
void RecentViews::show(
|
||||
RecentViewsData data,
|
||||
rpl::producer<Data::ReactionId> likedValue) {
|
||||
const auto guard = gsl::finally([&] {
|
||||
if (_likeIcon && likedValue) {
|
||||
std::move(
|
||||
likedValue
|
||||
) | rpl::map([](const Data::ReactionId &id) {
|
||||
return !id.empty();
|
||||
}) | rpl::start_with_next([=](bool liked) {
|
||||
const auto icon = liked
|
||||
? &st::storiesComposeControls.liked
|
||||
: &st::storiesLikesIcon;
|
||||
_likeIcon->setIconOverride(icon, icon);
|
||||
}, _likeIcon->lifetime());
|
||||
}
|
||||
});
|
||||
|
||||
if (_data == data) {
|
||||
return;
|
||||
}
|
||||
|
@ -137,27 +155,49 @@ void RecentViews::show(RecentViewsData data) {
|
|||
|| (_data.reactions != data.reactions);
|
||||
const auto usersChanged = !_userpics || (_data.list != data.list);
|
||||
_data = data;
|
||||
if (!_data.valid) {
|
||||
if (!_data.self) {
|
||||
_text = {};
|
||||
_clickHandlerLifetime.destroy();
|
||||
_userpicsLifetime.destroy();
|
||||
_userpics = nullptr;
|
||||
_widget = nullptr;
|
||||
return;
|
||||
} else {
|
||||
if (!_widget) {
|
||||
setupWidget();
|
||||
}
|
||||
if (!_userpics) {
|
||||
setupUserpics();
|
||||
}
|
||||
if (countersChanged) {
|
||||
updateText();
|
||||
}
|
||||
if (usersChanged) {
|
||||
updateUserpics();
|
||||
}
|
||||
refreshClickHandler();
|
||||
}
|
||||
if (!_widget) {
|
||||
setupWidget();
|
||||
|
||||
if (!_data.channel) {
|
||||
_likeIcon = nullptr;
|
||||
_likeWrap = nullptr;
|
||||
_viewsWrap = nullptr;
|
||||
} else {
|
||||
_viewsCounter = Lang::FormatCountDecimal(std::max(_data.total, 1));
|
||||
_likesCounter = _data.reactions
|
||||
? Lang::FormatCountDecimal(_data.reactions)
|
||||
: QString();
|
||||
if (!_likeWrap || !_likeIcon || !_viewsWrap) {
|
||||
setupViewsReactions();
|
||||
}
|
||||
}
|
||||
if (!_userpics) {
|
||||
setupUserpics();
|
||||
}
|
||||
if (countersChanged) {
|
||||
updateText();
|
||||
}
|
||||
if (usersChanged) {
|
||||
updateUserpics();
|
||||
}
|
||||
refreshClickHandler();
|
||||
}
|
||||
|
||||
Ui::RpWidget *RecentViews::likeButton() const {
|
||||
return _likeWrap.get();
|
||||
}
|
||||
|
||||
Ui::RpWidget *RecentViews::likeIconWidget() const {
|
||||
return _likeIcon.get();
|
||||
}
|
||||
|
||||
void RecentViews::refreshClickHandler() {
|
||||
|
@ -236,6 +276,74 @@ void RecentViews::setupWidget() {
|
|||
}, raw->lifetime());
|
||||
}
|
||||
|
||||
void RecentViews::setupViewsReactions() {
|
||||
_viewsWrap = std::make_unique<Ui::RpWidget>(_controller->wrap());
|
||||
_likeWrap = std::make_unique<Ui::AbstractButton>(_controller->wrap());
|
||||
_likeIcon = std::make_unique<Ui::IconButton>(
|
||||
_likeWrap.get(),
|
||||
st::storiesComposeControls.like);
|
||||
_likeIcon->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||
|
||||
_controller->layoutValue(
|
||||
) | rpl::start_with_next([=](const Layout &layout) {
|
||||
_outer = layout.views;
|
||||
updateViewsReactionsGeometry();
|
||||
}, _likeWrap->lifetime());
|
||||
|
||||
const auto views = Ui::CreateChild<Ui::FlatLabel>(
|
||||
_viewsWrap.get(),
|
||||
_viewsCounter.value(),
|
||||
st::storiesViewsText);
|
||||
views->show();
|
||||
views->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||
views->move(st::storiesViewsTextPosition);
|
||||
|
||||
views->widthValue(
|
||||
) | rpl::start_with_next([=](int width) {
|
||||
_viewsWrap->resize(views->x() + width, _likeIcon->height());
|
||||
updateViewsReactionsGeometry();
|
||||
}, _viewsWrap->lifetime());
|
||||
_viewsWrap->paintRequest() | rpl::start_with_next([=] {
|
||||
auto p = QPainter(_viewsWrap.get());
|
||||
const auto &icon = st::storiesViewsIcon;
|
||||
const auto top = (_viewsWrap->height() - icon.height()) / 2;
|
||||
icon.paint(p, 0, top, _viewsWrap->width());
|
||||
}, _viewsWrap->lifetime());
|
||||
|
||||
_likeIcon->move(0, 0);
|
||||
const auto likes = Ui::CreateChild<Ui::FlatLabel>(
|
||||
_likeWrap.get(),
|
||||
_likesCounter.value(),
|
||||
st::storiesLikesText);
|
||||
likes->show();
|
||||
likes->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||
likes->move(st::storiesLikesTextPosition);
|
||||
|
||||
likes->widthValue(
|
||||
) | rpl::start_with_next([=](int width) {
|
||||
width += width
|
||||
? st::storiesLikesTextRightSkip
|
||||
: st::storiesLieksEmptyRightSkip;
|
||||
_likeWrap->resize(likes->x() + width, _likeIcon->height());
|
||||
updateViewsReactionsGeometry();
|
||||
}, _likeWrap->lifetime());
|
||||
|
||||
_viewsWrap->show();
|
||||
_likeIcon->show();
|
||||
_likeWrap->show();
|
||||
|
||||
_likeWrap->setClickedCallback([=] {
|
||||
_controller->toggleLiked();
|
||||
});
|
||||
}
|
||||
|
||||
void RecentViews::updateViewsReactionsGeometry() {
|
||||
_viewsWrap->move(_outer.topLeft() + st::storiesViewsPosition);
|
||||
_likeWrap->move(_outer.topLeft()
|
||||
+ QPoint(_outer.width() - _likeWrap->width(), 0)
|
||||
+ st::storiesLikesPosition);
|
||||
}
|
||||
|
||||
void RecentViews::updatePartsGeometry() {
|
||||
const auto skip = st::storiesRecentViewsSkip;
|
||||
const auto full = _userpicsWidth + skip + _text.maxWidth();
|
||||
|
|
|
@ -13,9 +13,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
|
||||
namespace Data {
|
||||
struct StoryView;
|
||||
struct ReactionId;
|
||||
} // namespace Data
|
||||
|
||||
namespace Ui {
|
||||
class AbstractButton;
|
||||
class IconButton;
|
||||
class RpWidget;
|
||||
class GroupCallUserpics;
|
||||
class PopupMenu;
|
||||
|
@ -34,7 +37,8 @@ struct RecentViewsData {
|
|||
std::vector<not_null<PeerData*>> list;
|
||||
int reactions = 0;
|
||||
int total = 0;
|
||||
bool valid = false;
|
||||
bool self = false;
|
||||
bool channel = false;
|
||||
|
||||
friend inline auto operator<=>(
|
||||
const RecentViewsData &,
|
||||
|
@ -49,7 +53,12 @@ public:
|
|||
explicit RecentViews(not_null<Controller*> controller);
|
||||
~RecentViews();
|
||||
|
||||
void show(RecentViewsData data);
|
||||
void show(
|
||||
RecentViewsData data,
|
||||
rpl::producer<Data::ReactionId> likedValue = nullptr);
|
||||
|
||||
[[nodiscard]] Ui::RpWidget *likeButton() const;
|
||||
[[nodiscard]] Ui::RpWidget *likeIconWidget() const;
|
||||
|
||||
private:
|
||||
struct MenuEntry {
|
||||
|
@ -69,6 +78,9 @@ private:
|
|||
void updatePartsGeometry();
|
||||
void showMenu();
|
||||
|
||||
void setupViewsReactions();
|
||||
void updateViewsReactionsGeometry();
|
||||
|
||||
void addMenuRow(Data::StoryView entry, const QDateTime &now);
|
||||
void addMenuRowPlaceholder(not_null<Main::Session*> session);
|
||||
void rebuildMenuTail();
|
||||
|
@ -83,6 +95,12 @@ private:
|
|||
RecentViewsData _data;
|
||||
rpl::lifetime _userpicsLifetime;
|
||||
|
||||
rpl::variable<QString> _viewsCounter;
|
||||
rpl::variable<QString> _likesCounter;
|
||||
std::unique_ptr<Ui::RpWidget> _viewsWrap;
|
||||
std::unique_ptr<Ui::AbstractButton> _likeWrap;
|
||||
std::unique_ptr<Ui::IconButton> _likeIcon;
|
||||
|
||||
base::unique_qptr<Ui::PopupMenu> _menu;
|
||||
rpl::lifetime _menuShortLifetime;
|
||||
std::vector<MenuEntry> _menuEntries;
|
||||
|
|
|
@ -991,3 +991,20 @@ storiesStealthBoxBottom: 11px;
|
|||
storiesStealthToast: Toast(defaultMultilineToast) {
|
||||
maxWidth: 340px;
|
||||
}
|
||||
|
||||
storiesViewsPosition: point(4px, 29px);
|
||||
storiesViewsIcon: icon{{ "mediaview/views", storiesComposeGrayText }};
|
||||
storiesViewsText: FlatLabel(defaultFlatLabel) {
|
||||
textFg: storiesComposeGrayText;
|
||||
}
|
||||
storiesViewsTextPosition: point(26px, 14px);
|
||||
|
||||
storiesLikesPosition: point(0px, 29px);
|
||||
storiesLikesIcon: icon {{ "chat/input_like", storiesComposeWhiteText }};
|
||||
storiesLikesText: FlatLabel(defaultFlatLabel) {
|
||||
textFg: storiesComposeWhiteText;
|
||||
style: semiboldTextStyle;
|
||||
}
|
||||
storiesLikesTextPosition: point(41px, 14px);
|
||||
storiesLikesTextRightSkip: 8px;
|
||||
storiesLieksEmptyRightSkip: 2px;
|
||||
|
|
|
@ -213,7 +213,7 @@ void EditInviteLinkBox(
|
|||
? tr::lng_group_invite_usage_any(tr::now)
|
||||
: !limit
|
||||
? tr::lng_group_invite_usage_custom(tr::now)
|
||||
: QString("%L1").arg(limit);
|
||||
: Lang::FormatCountDecimal(limit);
|
||||
state->usageButtons.emplace(
|
||||
limit,
|
||||
addButton(usagesWrap, usageGroup, limit, text));
|
||||
|
|
Loading…
Add table
Reference in a new issue