Support active selection in recommendations.
This commit is contained in:
parent
705bd9693d
commit
4f365c73ad
|
@ -734,9 +734,9 @@ auto PeerListRow::generateNameWords() const
|
||||||
return peer()->nameWords();
|
return peer()->nameWords();
|
||||||
}
|
}
|
||||||
|
|
||||||
QPoint PeerListRow::computeNamePosition(
|
const style::PeerListItem &PeerListRow::computeSt(
|
||||||
const style::PeerListItem &st) const {
|
const style::PeerListItem &st) const {
|
||||||
return st.namePosition;
|
return st;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PeerListRow::invalidatePixmapsCache() {
|
void PeerListRow::invalidatePixmapsCache() {
|
||||||
|
@ -1693,7 +1693,9 @@ crl::time PeerListContent::paintRow(
|
||||||
const auto row = getRow(index);
|
const auto row = getRow(index);
|
||||||
Assert(row != nullptr);
|
Assert(row != nullptr);
|
||||||
|
|
||||||
row->lazyInitialize(_st.item);
|
const auto &st = row->computeSt(_st.item);
|
||||||
|
|
||||||
|
row->lazyInitialize(st);
|
||||||
const auto outerWidth = width();
|
const auto outerWidth = width();
|
||||||
|
|
||||||
auto refreshStatusAt = row->refreshStatusTime();
|
auto refreshStatusAt = row->refreshStatusTime();
|
||||||
|
@ -1721,8 +1723,8 @@ crl::time PeerListContent::paintRow(
|
||||||
|
|
||||||
const auto opacity = row->opacity();
|
const auto opacity = row->opacity();
|
||||||
const auto &bg = selected
|
const auto &bg = selected
|
||||||
? _st.item.button.textBgOver
|
? st.button.textBgOver
|
||||||
: _st.item.button.textBg;
|
: st.button.textBg;
|
||||||
if (opacity < 1.) {
|
if (opacity < 1.) {
|
||||||
p.setOpacity(opacity);
|
p.setOpacity(opacity);
|
||||||
}
|
}
|
||||||
|
@ -1736,34 +1738,34 @@ crl::time PeerListContent::paintRow(
|
||||||
row->paintRipple(p, 0, 0, outerWidth);
|
row->paintRipple(p, 0, 0, outerWidth);
|
||||||
row->paintUserpic(
|
row->paintUserpic(
|
||||||
p,
|
p,
|
||||||
_st.item,
|
st,
|
||||||
_st.item.photoPosition.x(),
|
st.photoPosition.x(),
|
||||||
_st.item.photoPosition.y(),
|
st.photoPosition.y(),
|
||||||
outerWidth);
|
outerWidth);
|
||||||
|
|
||||||
p.setPen(st::contactsNameFg);
|
p.setPen(st::contactsNameFg);
|
||||||
|
|
||||||
const auto skipRight = _st.item.photoPosition.x();
|
const auto skipRight = st.photoPosition.x();
|
||||||
const auto rightActionSize = row->rightActionSize();
|
const auto rightActionSize = row->rightActionSize();
|
||||||
const auto rightActionMargins = rightActionSize.isEmpty()
|
const auto rightActionMargins = rightActionSize.isEmpty()
|
||||||
? QMargins()
|
? QMargins()
|
||||||
: row->rightActionMargins();
|
: row->rightActionMargins();
|
||||||
const auto &name = row->name();
|
const auto &name = row->name();
|
||||||
const auto namePosition = row->computeNamePosition(_st.item);
|
const auto namePosition = st.namePosition;
|
||||||
const auto namex = namePosition.x();
|
const auto namex = namePosition.x();
|
||||||
const auto namey = namePosition.y();
|
const auto namey = namePosition.y();
|
||||||
auto namew = outerWidth - namex - skipRight;
|
auto namew = outerWidth - namex - skipRight;
|
||||||
if (!rightActionSize.isEmpty()
|
if (!rightActionSize.isEmpty()
|
||||||
&& (namey < rightActionMargins.top() + rightActionSize.height())
|
&& (namey < rightActionMargins.top() + rightActionSize.height())
|
||||||
&& (namey + _st.item.nameStyle.font->height
|
&& (namey + st.nameStyle.font->height
|
||||||
> rightActionMargins.top())) {
|
> rightActionMargins.top())) {
|
||||||
namew -= rightActionMargins.left()
|
namew -= rightActionMargins.left()
|
||||||
+ rightActionSize.width()
|
+ rightActionSize.width()
|
||||||
+ rightActionMargins.right()
|
+ rightActionMargins.right()
|
||||||
- skipRight;
|
- skipRight;
|
||||||
}
|
}
|
||||||
const auto statusx = _st.item.statusPosition.x();
|
const auto statusx = st.statusPosition.x();
|
||||||
const auto statusy = _st.item.statusPosition.y();
|
const auto statusy = st.statusPosition.y();
|
||||||
auto statusw = outerWidth - statusx - skipRight;
|
auto statusw = outerWidth - statusx - skipRight;
|
||||||
if (!rightActionSize.isEmpty()
|
if (!rightActionSize.isEmpty()
|
||||||
&& (statusy < rightActionMargins.top() + rightActionSize.height())
|
&& (statusy < rightActionMargins.top() + rightActionSize.height())
|
||||||
|
@ -1785,7 +1787,7 @@ crl::time PeerListContent::paintRow(
|
||||||
width(),
|
width(),
|
||||||
selected);
|
selected);
|
||||||
auto nameCheckedRatio = row->disabled() ? 0. : row->checkedRatio();
|
auto nameCheckedRatio = row->disabled() ? 0. : row->checkedRatio();
|
||||||
p.setPen(anim::pen(_st.item.nameFg, _st.item.nameFgChecked, nameCheckedRatio));
|
p.setPen(anim::pen(st.nameFg, st.nameFgChecked, nameCheckedRatio));
|
||||||
name.drawLeftElided(p, namex, namey, namew, width());
|
name.drawLeftElided(p, namex, namey, namew, width());
|
||||||
|
|
||||||
p.setFont(st::contactsStatusFont);
|
p.setFont(st::contactsStatusFont);
|
||||||
|
@ -1804,17 +1806,17 @@ crl::time PeerListContent::paintRow(
|
||||||
if (highlightedWidth > availableWidth) {
|
if (highlightedWidth > availableWidth) {
|
||||||
highlightedPart = st::contactsStatusFont->elided(highlightedPart, availableWidth);
|
highlightedPart = st::contactsStatusFont->elided(highlightedPart, availableWidth);
|
||||||
}
|
}
|
||||||
p.setPen(_st.item.statusFgActive);
|
p.setPen(st.statusFgActive);
|
||||||
p.drawTextLeft(statusx, statusy, width(), highlightedPart);
|
p.drawTextLeft(statusx, statusy, width(), highlightedPart);
|
||||||
} else {
|
} else {
|
||||||
grayedPart = st::contactsStatusFont->elided(grayedPart, availableWidth - highlightedWidth);
|
grayedPart = st::contactsStatusFont->elided(grayedPart, availableWidth - highlightedWidth);
|
||||||
p.setPen(_st.item.statusFgActive);
|
p.setPen(st.statusFgActive);
|
||||||
p.drawTextLeft(statusx, statusy, width(), highlightedPart);
|
p.drawTextLeft(statusx, statusy, width(), highlightedPart);
|
||||||
p.setPen(selected ? _st.item.statusFgOver : _st.item.statusFg);
|
p.setPen(selected ? st.statusFgOver : st.statusFg);
|
||||||
p.drawTextLeft(statusx + highlightedWidth, statusy, width(), grayedPart);
|
p.drawTextLeft(statusx + highlightedWidth, statusy, width(), grayedPart);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
row->paintStatusText(p, _st.item, statusx, statusy, statusw, width(), selected);
|
row->paintStatusText(p, st, statusx, statusy, statusw, width(), selected);
|
||||||
}
|
}
|
||||||
|
|
||||||
row->elementsPaint(
|
row->elementsPaint(
|
||||||
|
|
|
@ -100,7 +100,7 @@ public:
|
||||||
-> const base::flat_set<QChar> &;
|
-> const base::flat_set<QChar> &;
|
||||||
[[nodiscard]] virtual auto generateNameWords() const
|
[[nodiscard]] virtual auto generateNameWords() const
|
||||||
-> const base::flat_set<QString> &;
|
-> const base::flat_set<QString> &;
|
||||||
[[nodiscard]] virtual QPoint computeNamePosition(
|
[[nodiscard]] virtual const style::PeerListItem &computeSt(
|
||||||
const style::PeerListItem &st) const;
|
const style::PeerListItem &st) const;
|
||||||
|
|
||||||
virtual void preloadUserpic();
|
virtual void preloadUserpic();
|
||||||
|
|
|
@ -622,7 +622,23 @@ recentPeersList: PeerList(defaultPeerList) {
|
||||||
padding: margins(0px, 4px, 0px, 4px);
|
padding: margins(0px, 4px, 0px, 4px);
|
||||||
item: recentPeersItem;
|
item: recentPeersItem;
|
||||||
}
|
}
|
||||||
recentPeersSpecialNamePosition: point(64px, 19px);
|
recentPeersItemActive: PeerListItem(recentPeersItem) {
|
||||||
|
nameFg: dialogsNameFgActive;
|
||||||
|
nameFgChecked: dialogsNameFgActive;
|
||||||
|
button: OutlineButton(defaultPeerListButton) {
|
||||||
|
textBg: dialogsBgActive;
|
||||||
|
textBgOver: dialogsBgActive;
|
||||||
|
ripple: RippleAnimation(defaultRippleAnimation) {
|
||||||
|
color: dialogsRippleBgActive;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
statusFg: dialogsTextFgActive;
|
||||||
|
statusFgOver: dialogsTextFgActive;
|
||||||
|
statusFgActive: dialogsTextFgActive;
|
||||||
|
}
|
||||||
|
recentPeersSpecialName: PeerListItem(recentPeersItem) {
|
||||||
|
namePosition: point(64px, 19px);
|
||||||
|
}
|
||||||
|
|
||||||
dialogsSearchTabs: SettingsSlider(defaultSettingsSlider) {
|
dialogsSearchTabs: SettingsSlider(defaultSettingsSlider) {
|
||||||
height: 33px;
|
height: 33px;
|
||||||
|
|
|
@ -71,7 +71,8 @@ public:
|
||||||
bool actionSelected) override;
|
bool actionSelected) override;
|
||||||
bool rightActionDisabled() const override;
|
bool rightActionDisabled() const override;
|
||||||
|
|
||||||
QPoint computeNamePosition(const style::PeerListItem &st) const override;
|
const style::PeerListItem &computeSt(
|
||||||
|
const style::PeerListItem &st) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const not_null<History*> _history;
|
const not_null<History*> _history;
|
||||||
|
@ -120,6 +121,20 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ChannelRow final : public PeerListRow {
|
||||||
|
public:
|
||||||
|
using PeerListRow::PeerListRow;
|
||||||
|
|
||||||
|
void setActive(bool active);
|
||||||
|
|
||||||
|
const style::PeerListItem &computeSt(
|
||||||
|
const style::PeerListItem &st) const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool _active = false;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
class MyChannelsController final
|
class MyChannelsController final
|
||||||
: public PeerListController
|
: public PeerListController
|
||||||
, public base::has_weak_ptr {
|
, public base::has_weak_ptr {
|
||||||
|
@ -186,6 +201,7 @@ private:
|
||||||
|
|
||||||
const not_null<Window::SessionController*> _window;
|
const not_null<Window::SessionController*> _window;
|
||||||
rpl::variable<int> _count;
|
rpl::variable<int> _count;
|
||||||
|
History *_activeHistory = nullptr;
|
||||||
bool _requested = false;
|
bool _requested = false;
|
||||||
rpl::event_stream<not_null<PeerData*>> _chosen;
|
rpl::event_stream<not_null<PeerData*>> _chosen;
|
||||||
rpl::lifetime _lifetime;
|
rpl::lifetime _lifetime;
|
||||||
|
@ -367,10 +383,20 @@ bool RecentRow::rightActionDisabled() const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QPoint RecentRow::computeNamePosition(const style::PeerListItem &st) const {
|
const style::PeerListItem &RecentRow::computeSt(
|
||||||
|
const style::PeerListItem &st) const {
|
||||||
return (peer()->isSelf() || peer()->isRepliesChat())
|
return (peer()->isSelf() || peer()->isRepliesChat())
|
||||||
? st::recentPeersSpecialNamePosition
|
? st::recentPeersSpecialName
|
||||||
: st.namePosition;
|
: st;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChannelRow::setActive(bool active) {
|
||||||
|
_active = active;
|
||||||
|
}
|
||||||
|
|
||||||
|
const style::PeerListItem &ChannelRow::computeSt(
|
||||||
|
const style::PeerListItem &st) const {
|
||||||
|
return _active ? st::recentPeersItemActive : st::recentPeersItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
RecentsController::RecentsController(
|
RecentsController::RecentsController(
|
||||||
|
@ -763,10 +789,31 @@ void RecommendationsController::fill() {
|
||||||
}
|
}
|
||||||
delegate()->peerListRefreshRows();
|
delegate()->peerListRefreshRows();
|
||||||
_count = delegate()->peerListFullRowsCount();
|
_count = delegate()->peerListFullRowsCount();
|
||||||
|
|
||||||
|
_window->activeChatValue() | rpl::start_with_next([=](const Key &key) {
|
||||||
|
const auto history = key.history();
|
||||||
|
if (_activeHistory == history) {
|
||||||
|
return;
|
||||||
|
} else if (_activeHistory) {
|
||||||
|
const auto id = _activeHistory->peer->id.value;
|
||||||
|
if (const auto row = delegate()->peerListFindRow(id)) {
|
||||||
|
static_cast<ChannelRow*>(row)->setActive(false);
|
||||||
|
delegate()->peerListUpdateRow(row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_activeHistory = history;
|
||||||
|
if (_activeHistory) {
|
||||||
|
const auto id = _activeHistory->peer->id.value;
|
||||||
|
if (const auto row = delegate()->peerListFindRow(id)) {
|
||||||
|
static_cast<ChannelRow*>(row)->setActive(true);
|
||||||
|
delegate()->peerListUpdateRow(row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, _lifetime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RecommendationsController::appendRow(not_null<ChannelData*> channel) {
|
void RecommendationsController::appendRow(not_null<ChannelData*> channel) {
|
||||||
auto row = std::make_unique<PeerListRow>(channel);
|
auto row = std::make_unique<ChannelRow>(channel);
|
||||||
if (channel->membersCountKnown()) {
|
if (channel->membersCountKnown()) {
|
||||||
row->setCustomStatus((channel->isBroadcast()
|
row->setCustomStatus((channel->isBroadcast()
|
||||||
? tr::lng_chat_status_subscribers
|
? tr::lng_chat_status_subscribers
|
||||||
|
|
Loading…
Reference in New Issue