mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-09-08 21:13:29 +02:00
Show badges in new tabs.
This commit is contained in:
parent
8512154b45
commit
5943052cd1
5 changed files with 197 additions and 30 deletions
|
@ -93,6 +93,9 @@ struct BadgesState {
|
||||||
friend inline constexpr auto operator<=>(
|
friend inline constexpr auto operator<=>(
|
||||||
BadgesState,
|
BadgesState,
|
||||||
BadgesState) = default;
|
BadgesState) = default;
|
||||||
|
friend inline constexpr bool operator==(
|
||||||
|
BadgesState,
|
||||||
|
BadgesState) = default;
|
||||||
|
|
||||||
[[nodiscard]] bool empty() const {
|
[[nodiscard]] bool empty() const {
|
||||||
return !unread && !mention && !reaction;
|
return !unread && !mention && !reaction;
|
||||||
|
|
|
@ -180,11 +180,11 @@ void SubsectionTabs::setupSlider(
|
||||||
slider->sectionActivated() | rpl::start_with_next([=](int active) {
|
slider->sectionActivated() | rpl::start_with_next([=](int active) {
|
||||||
if (active >= 0
|
if (active >= 0
|
||||||
&& active < _slice.size()
|
&& active < _slice.size()
|
||||||
&& _active != _slice[active]) {
|
&& _active != _slice[active].thread) {
|
||||||
auto params = Window::SectionShow();
|
auto params = Window::SectionShow();
|
||||||
params.way = Window::SectionShow::Way::ClearStack;
|
params.way = Window::SectionShow::Way::ClearStack;
|
||||||
params.animated = anim::type::instant;
|
params.animated = anim::type::instant;
|
||||||
_controller->showThread(_slice[active], {}, params);
|
_controller->showThread(_slice[active].thread, {}, params);
|
||||||
}
|
}
|
||||||
}, slider->lifetime());
|
}, slider->lifetime());
|
||||||
|
|
||||||
|
@ -209,11 +209,11 @@ void SubsectionTabs::setupSlider(
|
||||||
if (availableFrom < full
|
if (availableFrom < full
|
||||||
&& _beforeSkipped.value_or(0) > 0
|
&& _beforeSkipped.value_or(0) > 0
|
||||||
&& !_slice.empty()) {
|
&& !_slice.empty()) {
|
||||||
_around = _slice.front();
|
_around = _slice.front().thread;
|
||||||
refreshSlice();
|
refreshSlice();
|
||||||
} else if (availableTill < full) {
|
} else if (availableTill < full) {
|
||||||
if (_afterAvailable > 0) {
|
if (_afterAvailable > 0) {
|
||||||
_around = _slice.back();
|
_around = _slice.back().thread;
|
||||||
refreshSlice();
|
refreshSlice();
|
||||||
} else if (!_afterSkipped.has_value()) {
|
} else if (!_afterSkipped.has_value()) {
|
||||||
_loading = true;
|
_loading = true;
|
||||||
|
@ -232,9 +232,9 @@ void SubsectionTabs::setupSlider(
|
||||||
};
|
};
|
||||||
auto sections = std::vector<Ui::SubsectionTab>();
|
auto sections = std::vector<Ui::SubsectionTab>();
|
||||||
auto activeIndex = -1;
|
auto activeIndex = -1;
|
||||||
for (const auto &thread : _slice) {
|
for (const auto &item : _slice) {
|
||||||
const auto index = int(sections.size());
|
const auto index = int(sections.size());
|
||||||
if (thread == _active) {
|
if (item.thread == _active) {
|
||||||
activeIndex = index;
|
activeIndex = index;
|
||||||
}
|
}
|
||||||
const auto textFg = [=] {
|
const auto textFg = [=] {
|
||||||
|
@ -243,23 +243,24 @@ void SubsectionTabs::setupSlider(
|
||||||
st::windowActiveTextFg,
|
st::windowActiveTextFg,
|
||||||
slider->buttonActive(slider->buttonAt(index)));
|
slider->buttonActive(slider->buttonAt(index)));
|
||||||
};
|
};
|
||||||
if (const auto topic = thread->asTopic()) {
|
if (const auto topic = item.thread->asTopic()) {
|
||||||
if (vertical) {
|
if (vertical) {
|
||||||
|
const auto general = topic->isGeneral();
|
||||||
sections.push_back({
|
sections.push_back({
|
||||||
.text = { topic->title() },
|
.text = { item.name },
|
||||||
.userpic = (topic->iconId()
|
.userpic = (item.iconId
|
||||||
? Ui::MakeEmojiThumbnail(
|
? Ui::MakeEmojiThumbnail(
|
||||||
&topic->owner(),
|
&topic->owner(),
|
||||||
Data::SerializeCustomEmojiId(topic->iconId()),
|
Data::SerializeCustomEmojiId(item.iconId),
|
||||||
paused,
|
paused,
|
||||||
textFg)
|
textFg)
|
||||||
: Ui::MakeEmojiThumbnail(
|
: Ui::MakeEmojiThumbnail(
|
||||||
&topic->owner(),
|
&topic->owner(),
|
||||||
Data::TopicIconEmojiEntity({
|
Data::TopicIconEmojiEntity({
|
||||||
.title = (topic->isGeneral()
|
.title = (general
|
||||||
? Data::ForumGeneralIconTitle()
|
? Data::ForumGeneralIconTitle()
|
||||||
: topic->title()),
|
: item.name),
|
||||||
.colorId = (topic->isGeneral()
|
.colorId = (general
|
||||||
? Data::ForumGeneralIconColor(
|
? Data::ForumGeneralIconColor(
|
||||||
st::windowSubTextFg->c)
|
st::windowSubTextFg->c)
|
||||||
: topic->colorId()),
|
: topic->colorId()),
|
||||||
|
@ -272,7 +273,7 @@ void SubsectionTabs::setupSlider(
|
||||||
.text = topic->titleWithIcon(),
|
.text = topic->titleWithIcon(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else if (const auto sublist = thread->asSublist()) {
|
} else if (const auto sublist = item.thread->asSublist()) {
|
||||||
const auto peer = sublist->sublistPeer();
|
const auto peer = sublist->sublistPeer();
|
||||||
if (vertical) {
|
if (vertical) {
|
||||||
sections.push_back({
|
sections.push_back({
|
||||||
|
@ -294,6 +295,8 @@ void SubsectionTabs::setupSlider(
|
||||||
.userpic = Ui::MakeAllSubsectionsThumbnail(textFg),
|
.userpic = Ui::MakeAllSubsectionsThumbnail(textFg),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
auto §ion = sections.back();
|
||||||
|
section.badges = item.badges;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto scrollSavingThread = (Data::Thread*)nullptr;
|
auto scrollSavingThread = (Data::Thread*)nullptr;
|
||||||
|
@ -309,21 +312,24 @@ void SubsectionTabs::setupSlider(
|
||||||
? slider->lookupSectionPosition(index + 1)
|
? slider->lookupSectionPosition(index + 1)
|
||||||
: (indexPosition + scrollValue + 1);
|
: (indexPosition + scrollValue + 1);
|
||||||
if (indexPosition <= scrollValue && nextPosition > scrollValue) {
|
if (indexPosition <= scrollValue && nextPosition > scrollValue) {
|
||||||
scrollSavingThread = _sectionsSlice[index];
|
scrollSavingThread = _sectionsSlice[index].thread;
|
||||||
scrollSavingShift = scrollValue - indexPosition;
|
scrollSavingShift = scrollValue - indexPosition;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
indexPosition = nextPosition;
|
indexPosition = nextPosition;
|
||||||
}
|
}
|
||||||
scrollSavingIndex = scrollSavingThread
|
scrollSavingIndex = scrollSavingThread
|
||||||
? int(ranges::find(_slice, not_null(scrollSavingThread))
|
? int(ranges::find(
|
||||||
- begin(_slice))
|
_slice,
|
||||||
|
not_null(scrollSavingThread),
|
||||||
|
&Item::thread
|
||||||
|
) - begin(_slice))
|
||||||
: -1;
|
: -1;
|
||||||
if (scrollSavingIndex == _slice.size()) {
|
if (scrollSavingIndex == _slice.size()) {
|
||||||
scrollSavingIndex = -1;
|
scrollSavingIndex = -1;
|
||||||
for (auto index = 0; index != count; ++index) {
|
for (auto index = 0; index != count; ++index) {
|
||||||
const auto thread = _sectionsSlice[index];
|
const auto thread = _sectionsSlice[index].thread;
|
||||||
if (ranges::contains(_slice, thread)) {
|
if (ranges::contains(_slice, thread, &Item::thread)) {
|
||||||
scrollSavingThread = thread;
|
scrollSavingThread = thread;
|
||||||
scrollSavingShift = scrollValue
|
scrollSavingShift = scrollValue
|
||||||
- slider->lookupSectionPosition(index);
|
- slider->lookupSectionPosition(index);
|
||||||
|
@ -483,6 +489,7 @@ void SubsectionTabs::setVisible(bool shown) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SubsectionTabs::track() {
|
void SubsectionTabs::track() {
|
||||||
|
using Event = Data::Session::ChatListEntryRefresh;
|
||||||
if (const auto forum = _history->peer->forum()) {
|
if (const auto forum = _history->peer->forum()) {
|
||||||
forum->topicDestroyed(
|
forum->topicDestroyed(
|
||||||
) | rpl::start_with_next([=](not_null<Data::ForumTopic*> topic) {
|
) | rpl::start_with_next([=](not_null<Data::ForumTopic*> topic) {
|
||||||
|
@ -491,6 +498,19 @@ void SubsectionTabs::track() {
|
||||||
refreshSlice();
|
refreshSlice();
|
||||||
}
|
}
|
||||||
}, _lifetime);
|
}, _lifetime);
|
||||||
|
|
||||||
|
forum->topicsList()->unreadStateChanges(
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
scheduleRefresh();
|
||||||
|
}, _lifetime);
|
||||||
|
|
||||||
|
forum->owner().chatListEntryRefreshes(
|
||||||
|
) | rpl::filter([=](const Event &event) {
|
||||||
|
const auto topic = event.filterId ? nullptr : event.key.topic();
|
||||||
|
return (topic && topic->forum() == forum);
|
||||||
|
}) | rpl::start_with_next([=] {
|
||||||
|
scheduleRefresh();
|
||||||
|
}, _lifetime);
|
||||||
} else if (const auto monoforum = _history->peer->monoforum()) {
|
} else if (const auto monoforum = _history->peer->monoforum()) {
|
||||||
monoforum->sublistDestroyed(
|
monoforum->sublistDestroyed(
|
||||||
) | rpl::start_with_next([=](not_null<Data::SavedSublist*> sublist) {
|
) | rpl::start_with_next([=](not_null<Data::SavedSublist*> sublist) {
|
||||||
|
@ -499,12 +519,29 @@ void SubsectionTabs::track() {
|
||||||
refreshSlice();
|
refreshSlice();
|
||||||
}
|
}
|
||||||
}, _lifetime);
|
}, _lifetime);
|
||||||
|
|
||||||
|
monoforum->chatsList()->unreadStateChanges(
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
scheduleRefresh();
|
||||||
|
}, _lifetime);
|
||||||
|
|
||||||
|
monoforum->owner().chatListEntryRefreshes(
|
||||||
|
) | rpl::filter([=](const Event &event) {
|
||||||
|
const auto sublist = event.filterId
|
||||||
|
? nullptr
|
||||||
|
: event.key.sublist();
|
||||||
|
return (sublist && sublist->parent() == monoforum);
|
||||||
|
}) | rpl::start_with_next([=] {
|
||||||
|
scheduleRefresh();
|
||||||
|
}, _lifetime);
|
||||||
} else {
|
} else {
|
||||||
Unexpected("Peer in SubsectionTabs::track.");
|
Unexpected("Peer in SubsectionTabs::track.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SubsectionTabs::refreshSlice() {
|
void SubsectionTabs::refreshSlice() {
|
||||||
|
_refreshScheduled = false;
|
||||||
|
|
||||||
const auto forum = _history->peer->forum();
|
const auto forum = _history->peer->forum();
|
||||||
const auto monoforum = _history->peer->monoforum();
|
const auto monoforum = _history->peer->monoforum();
|
||||||
Assert(forum || monoforum);
|
Assert(forum || monoforum);
|
||||||
|
@ -512,15 +549,25 @@ void SubsectionTabs::refreshSlice() {
|
||||||
const auto list = forum
|
const auto list = forum
|
||||||
? forum->topicsList()
|
? forum->topicsList()
|
||||||
: monoforum->chatsList();
|
: monoforum->chatsList();
|
||||||
auto slice = std::vector<not_null<Data::Thread*>>();
|
auto slice = std::vector<Item>();
|
||||||
|
slice.reserve(_slice.size() + 10);
|
||||||
const auto guard = gsl::finally([&] {
|
const auto guard = gsl::finally([&] {
|
||||||
if (_slice != slice) {
|
if (_slice != slice) {
|
||||||
_slice = std::move(slice);
|
_slice = std::move(slice);
|
||||||
_refreshed.fire({});
|
_refreshed.fire({});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
const auto push = [&](not_null<Data::Thread*> thread) {
|
||||||
|
const auto topic = thread->asTopic();
|
||||||
|
slice.push_back({
|
||||||
|
.thread = thread,
|
||||||
|
.badges = thread->chatListBadgesState(),
|
||||||
|
.iconId = topic ? topic->iconId() : DocumentId(),
|
||||||
|
.name = thread->chatListName(),
|
||||||
|
});
|
||||||
|
};
|
||||||
if (!list) {
|
if (!list) {
|
||||||
slice.push_back(_history);
|
push(_history);
|
||||||
_beforeSkipped = _afterSkipped = 0;
|
_beforeSkipped = _afterSkipped = 0;
|
||||||
_afterAvailable = 0;
|
_afterAvailable = 0;
|
||||||
return;
|
return;
|
||||||
|
@ -542,13 +589,25 @@ void SubsectionTabs::refreshSlice() {
|
||||||
_afterAvailable = std::max(0, int(chats.end() - till));
|
_afterAvailable = std::max(0, int(chats.end() - till));
|
||||||
_afterSkipped = list->loaded() ? _afterAvailable : std::optional<int>();
|
_afterSkipped = list->loaded() ? _afterAvailable : std::optional<int>();
|
||||||
if (from == chats.begin()) {
|
if (from == chats.begin()) {
|
||||||
slice.push_back(_history);
|
push(_history);
|
||||||
}
|
}
|
||||||
for (auto i = from; i != till; ++i) {
|
for (auto i = from; i != till; ++i) {
|
||||||
slice.push_back((*i)->thread());
|
push((*i)->thread());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SubsectionTabs::scheduleRefresh() {
|
||||||
|
if (_refreshScheduled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_refreshScheduled = true;
|
||||||
|
InvokeQueued(_shadow, [=] {
|
||||||
|
if (_refreshScheduled) {
|
||||||
|
refreshSlice();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
bool SubsectionTabs::switchTo(
|
bool SubsectionTabs::switchTo(
|
||||||
not_null<Data::Thread*> thread,
|
not_null<Data::Thread*> thread,
|
||||||
not_null<Ui::RpWidget*> parent) {
|
not_null<Ui::RpWidget*> parent) {
|
||||||
|
|
|
@ -7,6 +7,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "dialogs/dialogs_common.h"
|
||||||
|
|
||||||
class History;
|
class History;
|
||||||
|
|
||||||
namespace Data {
|
namespace Data {
|
||||||
|
@ -53,12 +55,27 @@ public:
|
||||||
void hide();
|
void hide();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
struct Item {
|
||||||
|
not_null<Data::Thread*> thread;
|
||||||
|
Dialogs::BadgesState badges;
|
||||||
|
DocumentId iconId = 0;
|
||||||
|
QString name;
|
||||||
|
|
||||||
|
friend inline constexpr auto operator<=>(
|
||||||
|
const Item &,
|
||||||
|
const Item &) = default;
|
||||||
|
friend inline constexpr bool operator==(
|
||||||
|
const Item &,
|
||||||
|
const Item &) = default;
|
||||||
|
};
|
||||||
|
|
||||||
void track();
|
void track();
|
||||||
void setupHorizontal(not_null<QWidget*> parent);
|
void setupHorizontal(not_null<QWidget*> parent);
|
||||||
void setupVertical(not_null<QWidget*> parent);
|
void setupVertical(not_null<QWidget*> parent);
|
||||||
void toggleModes();
|
void toggleModes();
|
||||||
void setVisible(bool shown);
|
void setVisible(bool shown);
|
||||||
void refreshSlice();
|
void refreshSlice();
|
||||||
|
void scheduleRefresh();
|
||||||
void loadMore();
|
void loadMore();
|
||||||
[[nodiscard]] rpl::producer<> dataChanged() const;
|
[[nodiscard]] rpl::producer<> dataChanged() const;
|
||||||
|
|
||||||
|
@ -74,8 +91,8 @@ private:
|
||||||
Ui::RpWidget *_vertical = nullptr;
|
Ui::RpWidget *_vertical = nullptr;
|
||||||
Ui::RpWidget *_shadow = nullptr;
|
Ui::RpWidget *_shadow = nullptr;
|
||||||
|
|
||||||
std::vector<not_null<Data::Thread*>> _slice;
|
std::vector<Item> _slice;
|
||||||
std::vector<not_null<Data::Thread*>> _sectionsSlice;
|
std::vector<Item> _sectionsSlice;
|
||||||
|
|
||||||
not_null<Data::Thread*> _active;
|
not_null<Data::Thread*> _active;
|
||||||
not_null<Data::Thread*> _around;
|
not_null<Data::Thread*> _around;
|
||||||
|
@ -83,6 +100,7 @@ private:
|
||||||
int _afterLimit = 0;
|
int _afterLimit = 0;
|
||||||
int _afterAvailable = 0;
|
int _afterAvailable = 0;
|
||||||
bool _loading = false;
|
bool _loading = false;
|
||||||
|
bool _refreshScheduled = false;
|
||||||
std::optional<int> _beforeSkipped;
|
std::optional<int> _beforeSkipped;
|
||||||
std::optional<int> _afterSkipped;
|
std::optional<int> _afterSkipped;
|
||||||
|
|
||||||
|
|
|
@ -8,9 +8,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/controls/subsection_tabs_slider.h"
|
#include "ui/controls/subsection_tabs_slider.h"
|
||||||
|
|
||||||
#include "base/call_delayed.h"
|
#include "base/call_delayed.h"
|
||||||
|
#include "dialogs/dialogs_three_state_icon.h"
|
||||||
#include "ui/effects/ripple_animation.h"
|
#include "ui/effects/ripple_animation.h"
|
||||||
#include "ui/dynamic_image.h"
|
#include "ui/dynamic_image.h"
|
||||||
|
#include "ui/unread_badge_paint.h"
|
||||||
#include "styles/style_chat.h"
|
#include "styles/style_chat.h"
|
||||||
|
#include "styles/style_dialogs.h"
|
||||||
#include "styles/style_filter_icons.h"
|
#include "styles/style_filter_icons.h"
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
|
@ -105,6 +108,41 @@ void VerticalButton::paintEvent(QPaintEvent *e) {
|
||||||
.align = style::al_top,
|
.align = style::al_top,
|
||||||
.paused = _delegate->buttonPaused(),
|
.paused = _delegate->buttonPaused(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const auto &state = _data.badges;
|
||||||
|
const auto top = _st.userpicTop / 2;
|
||||||
|
auto right = width() - textLeft;
|
||||||
|
UnreadBadgeStyle st;
|
||||||
|
if (state.unread) {
|
||||||
|
st.muted = state.unreadMuted;
|
||||||
|
const auto counter = (state.unreadCounter <= 0)
|
||||||
|
? QString()
|
||||||
|
: ((state.mention || state.reaction)
|
||||||
|
&& (state.unreadCounter > 999))
|
||||||
|
? (u"99+"_q)
|
||||||
|
: (state.unreadCounter > 999999)
|
||||||
|
? (u"99999+"_q)
|
||||||
|
: QString::number(state.unreadCounter);
|
||||||
|
const auto badge = PaintUnreadBadge(p, counter, right, top, st);
|
||||||
|
right -= badge.width() + st.padding;
|
||||||
|
}
|
||||||
|
if (state.mention || state.reaction) {
|
||||||
|
UnreadBadgeStyle st;
|
||||||
|
st.sizeId = state.mention
|
||||||
|
? UnreadBadgeSize::Dialogs
|
||||||
|
: UnreadBadgeSize::ReactionInDialogs;
|
||||||
|
st.muted = state.mention
|
||||||
|
? state.mentionMuted
|
||||||
|
: state.reactionMuted;
|
||||||
|
st.padding = 0;
|
||||||
|
st.textTop = 0;
|
||||||
|
const auto counter = QString();
|
||||||
|
const auto badge = PaintUnreadBadge(p, counter, right, top, st);
|
||||||
|
(state.mention
|
||||||
|
? st::dialogsUnreadMention.icon
|
||||||
|
: st::dialogsUnreadReaction.icon).paintInCenter(p, badge);
|
||||||
|
right -= badge.width() + st.padding + st::dialogsUnreadPadding;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HorizontalButton::HorizontalButton(
|
HorizontalButton::HorizontalButton(
|
||||||
|
@ -118,7 +156,28 @@ HorizontalButton::HorizontalButton(
|
||||||
}
|
}
|
||||||
|
|
||||||
void HorizontalButton::updateSize() {
|
void HorizontalButton::updateSize() {
|
||||||
resize(_st.strictSkip + _text.maxWidth(), _st.height);
|
auto width = _st.strictSkip + _text.maxWidth();
|
||||||
|
|
||||||
|
const auto &state = _data.badges;
|
||||||
|
UnreadBadgeStyle st;
|
||||||
|
if (state.unread) {
|
||||||
|
const auto counter = (state.unreadCounter <= 0)
|
||||||
|
? QString()
|
||||||
|
: QString::number(state.unreadCounter);
|
||||||
|
const auto badge = CountUnreadBadgeSize(counter, st);
|
||||||
|
width += badge.width() + st.padding;
|
||||||
|
}
|
||||||
|
if (state.mention || state.reaction) {
|
||||||
|
st.sizeId = state.mention
|
||||||
|
? UnreadBadgeSize::Dialogs
|
||||||
|
: UnreadBadgeSize::ReactionInDialogs;
|
||||||
|
st.padding = 0;
|
||||||
|
st.textTop = 0;
|
||||||
|
const auto counter = QString();
|
||||||
|
const auto badge = CountUnreadBadgeSize(counter, st);
|
||||||
|
width += badge.width() + st.padding + st::dialogsUnreadPadding;
|
||||||
|
}
|
||||||
|
resize(width, _st.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HorizontalButton::dataUpdatedHook() {
|
void HorizontalButton::dataUpdatedHook() {
|
||||||
|
@ -149,6 +208,36 @@ void HorizontalButton::paintEvent(QPaintEvent *e) {
|
||||||
.availableWidth = _text.maxWidth(),
|
.availableWidth = _text.maxWidth(),
|
||||||
.paused = _delegate->buttonPaused(),
|
.paused = _delegate->buttonPaused(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
auto right = width() - _st.strictSkip + (_st.strictSkip / 2);
|
||||||
|
UnreadBadgeStyle st;
|
||||||
|
const auto &state = _data.badges;
|
||||||
|
const auto badgeTop = (height() - st.size) / 2;
|
||||||
|
if (state.unread) {
|
||||||
|
st.muted = state.unreadMuted;
|
||||||
|
const auto counter = (state.unreadCounter <= 0)
|
||||||
|
? QString()
|
||||||
|
: QString::number(state.unreadCounter);
|
||||||
|
const auto badge = PaintUnreadBadge(p, counter, right, badgeTop, st);
|
||||||
|
right -= badge.width() + st.padding;
|
||||||
|
}
|
||||||
|
if (state.mention || state.reaction) {
|
||||||
|
UnreadBadgeStyle st;
|
||||||
|
st.sizeId = state.mention
|
||||||
|
? UnreadBadgeSize::Dialogs
|
||||||
|
: UnreadBadgeSize::ReactionInDialogs;
|
||||||
|
st.muted = state.mention
|
||||||
|
? state.mentionMuted
|
||||||
|
: state.reactionMuted;
|
||||||
|
st.padding = 0;
|
||||||
|
st.textTop = 0;
|
||||||
|
const auto counter = QString();
|
||||||
|
const auto badge = PaintUnreadBadge(p, counter, right, badgeTop, st);
|
||||||
|
(state.mention
|
||||||
|
? st::dialogsUnreadMention.icon
|
||||||
|
: st::dialogsUnreadReaction.icon).paintInCenter(p, badge);
|
||||||
|
right -= badge.width() + st.padding + st::dialogsUnreadPadding;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "dialogs/dialogs_common.h"
|
||||||
#include "ui/round_rect.h"
|
#include "ui/round_rect.h"
|
||||||
#include "ui/rp_widget.h"
|
#include "ui/rp_widget.h"
|
||||||
#include "ui/widgets/buttons.h"
|
#include "ui/widgets/buttons.h"
|
||||||
|
@ -25,10 +26,7 @@ class SubsectionButton;
|
||||||
struct SubsectionTab {
|
struct SubsectionTab {
|
||||||
TextWithEntities text;
|
TextWithEntities text;
|
||||||
std::shared_ptr<DynamicImage> userpic;
|
std::shared_ptr<DynamicImage> userpic;
|
||||||
int counter = 0;
|
Dialogs::BadgesState badges;
|
||||||
bool muted = false;
|
|
||||||
bool mention = false;
|
|
||||||
bool reaciton = false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SubsectionTabs {
|
struct SubsectionTabs {
|
||||||
|
|
Loading…
Add table
Reference in a new issue