Display feed userpic in single column layout.

This commit is contained in:
John Preston 2018-01-30 17:31:25 +03:00
parent 9f3048c1dc
commit 5ebecb4de3
9 changed files with 189 additions and 24 deletions

View File

@ -203,6 +203,8 @@ void Feed::setChannels(std::vector<not_null<ChannelData*>> channels) {
_channels.push_back(App::history(channel));
}
_channelsLoaded = true;
_parent->notifyFeedUpdated(this, FeedUpdateFlag::Channels);
}
bool Feed::justSetLastMessage(not_null<HistoryItem*> item) {

View File

@ -116,11 +116,13 @@ Widget::Widget(
rpl::single(
Data::FeedUpdate{ _feed, Data::FeedUpdateFlag::Channels }
) | rpl::then(
Auth().data().feedUpdated()
) | rpl::filter([=](const Data::FeedUpdate &update) {
return (update.feed == _feed);
}) | rpl::start_with_next([=](const Data::FeedUpdate &update) {
checkForSingleChannelFeed();
Auth().data().feedUpdated(
) | rpl::filter([=](const Data::FeedUpdate &update) {
return (update.feed == _feed)
&& (update.flag == Data::FeedUpdateFlag::Channels);
})
) | rpl::start_with_next([=] {
crl::on_main(this, [=] { checkForSingleChannelFeed(); });
}, lifetime());
}

View File

@ -355,16 +355,7 @@ void TopBarWidget::setActiveChat(Dialogs::Key chat) {
update();
updateUnreadBadge();
if (const auto peer = _activeChat.peer()) {
_info.create(
this,
_controller,
peer,
Ui::UserpicButton::Role::Custom,
st::topBarInfoButton);
_info->showSavedMessagesOnSelf(true);
_info->setAttribute(Qt::WA_TransparentForMouseEvents);
}
refreshInfoButton();
if (_menu) {
_menuToggle->removeEventFilter(_menu);
_menu->hideFast();
@ -374,6 +365,28 @@ void TopBarWidget::setActiveChat(Dialogs::Key chat) {
}
}
void TopBarWidget::refreshInfoButton() {
if (const auto peer = _activeChat.peer()) {
auto info = object_ptr<Ui::UserpicButton>(
this,
_controller,
peer,
Ui::UserpicButton::Role::Custom,
st::topBarInfoButton);
info->showSavedMessagesOnSelf(true);
_info = std::move(info);
} else if (const auto feed = _activeChat.feed()) {
_info = object_ptr<Ui::FeedUserpicButton>(
this,
_controller,
feed,
st::topBarFeedInfoButton);
}
if (_info) {
_info->setAttribute(Qt::WA_TransparentForMouseEvents);
}
}
void TopBarWidget::resizeEvent(QResizeEvent *e) {
updateControlsGeometry();
}

View File

@ -12,7 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "dialogs/dialogs_key.h"
namespace Ui {
class UserpicButton;
class AbstractButton;
class RoundButton;
class IconButton;
class DropdownMenu;
@ -67,6 +67,7 @@ protected:
int resizeGetHeight(int newWidth) override;
private:
void refreshInfoButton();
void refreshLang();
void updateControlsGeometry();
void selectedShowCallback();
@ -107,7 +108,7 @@ private:
object_ptr<Ui::IconButton> _back;
object_ptr<Ui::UnreadBadge> _unreadBadge = { nullptr };
object_ptr<Ui::UserpicButton> _info = { nullptr };
object_ptr<Ui::AbstractButton> _info = { nullptr };
object_ptr<Ui::IconButton> _call;
object_ptr<Ui::IconButton> _search;

View File

@ -661,8 +661,20 @@ topBarInfo: IconButton(topBarSearch) {
topBarInfoActive: icon {{ "top_bar_profile", windowActiveTextFg }};
topBarActionSkip: 10px;
topBarInfoButtonSize: size(52px, topBarHeight);
topBarInfoButtonInnerSize: 42px;
topBarInfoButtonInnerPosition: point(2px, -1px);
topBarInfoButton: UserpicButton(defaultUserpicButton) {
size: size(52px, topBarHeight);
photoSize: 42px;
photoPosition: point(2px, -1px);
size: topBarInfoButtonSize;
photoSize: topBarInfoButtonInnerSize;
photoPosition: topBarInfoButtonInnerPosition;
}
topBarFeedInfoButton: FeedUserpicButton(defaultFeedUserpicButton) {
size: topBarInfoButtonSize;
innerSize: topBarInfoButtonInnerSize;
innerPosition: topBarInfoButtonInnerPosition;
innerPart: UserpicButton(defaultUserpicButton) {
size: size(20px, 20px);
photoSize: 20px;
}
}

View File

@ -2203,6 +2203,11 @@ void MainWidget::ui_showPeerHistory(
}
updateControlsGeometry();
if (noPeer) {
_controller->setActiveChatEntry(Dialogs::Key());
}
if (onlyDialogs) {
_history->hide();
if (!_a_show.animating()) {
@ -2250,10 +2255,6 @@ void MainWidget::ui_showPeerHistory(
_dialogs->update();
}
if (noPeer) {
_controller->setActiveChatEntry(Dialogs::Key());
}
checkFloatPlayerVisibility();
}

View File

@ -14,6 +14,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/empty_userpic.h"
#include "data/data_photo.h"
#include "data/data_session.h"
#include "data/data_feed.h"
#include "history/history.h"
#include "core/file_utilities.h"
#include "boxes/photo_crop_box.h"
#include "boxes/confirm_box.h"
@ -824,6 +826,94 @@ void UserpicButton::prepareUserpicPixmap() {
: StorageKey();
}
FeedUserpicButton::FeedUserpicButton(
QWidget *parent,
not_null<Window::Controller*> controller,
not_null<Data::Feed*> feed,
const style::FeedUserpicButton &st)
: AbstractButton(parent)
, _st(st)
, _controller(controller)
, _feed(feed) {
prepare();
}
void FeedUserpicButton::prepare() {
resize(_st.size);
Auth().data().feedUpdated(
) | rpl::filter([=](const Data::FeedUpdate &update) {
return (update.feed == _feed)
&& (update.flag == Data::FeedUpdateFlag::Channels);
}) | rpl::start_with_next([=] {
crl::on_main(this, [=] { checkParts(); });
}, lifetime());
refreshParts();
}
void FeedUserpicButton::checkParts() {
if (!partsAreValid()) {
refreshParts();
}
}
bool FeedUserpicButton::partsAreValid() const {
const auto &channels = _feed->channels();
if (std::min(int(channels.size()), 4) != _parts.size()) {
return false;
}
for (auto i = 0; i != 4; ++i) {
if (channels[i]->peer != _parts[i].channel) {
return false;
}
}
return true;
}
void FeedUserpicButton::refreshParts() {
const auto &channels = _feed->channels();
const auto count = std::min(int(channels.size()), 4);
const auto createButton = [&](not_null<ChannelData*> channel) {
auto result = base::make_unique_q<Ui::UserpicButton>(
this,
_controller,
channel,
Ui::UserpicButton::Role::Custom,
_st.innerPart);
result->setAttribute(Qt::WA_TransparentForMouseEvents);
result->show();
return result;
};
const auto position = countInnerPosition();
auto x = position.x();
auto y = position.y();
const auto delta = _st.innerSize - _st.innerPart.photoSize;
_parts.clear();
for (auto i = 0; i != count; ++i) {
const auto channel = channels[i]->peer->asChannel();
_parts.push_back({ channel, createButton(channel) });
_parts.back().button->moveToLeft(x, y);
switch (i) {
case 0:
case 2: x += delta; break;
case 1: x -= delta; y += delta; break;
}
}
}
QPoint FeedUserpicButton::countInnerPosition() const {
auto innerLeft = (_st.innerPosition.x() < 0)
? (width() - _st.innerSize) / 2
: _st.innerPosition.x();
auto innerTop = (_st.innerPosition.y() < 0)
? (height() - _st.innerSize) / 2
: _st.innerPosition.y();
return { innerLeft, innerTop };
}
SilentToggle::SilentToggle(QWidget *parent, not_null<ChannelData*> channel)
: IconButton(parent, st::historySilentToggle)
, _channel(channel)

View File

@ -14,6 +14,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
class PeerData;
namespace Data {
class Feed;
} // namespace Data
namespace Window {
class Controller;
} // namespace Window
@ -218,6 +222,33 @@ private:
};
class FeedUserpicButton : public AbstractButton {
public:
FeedUserpicButton(
QWidget *parent,
not_null<Window::Controller*> controller,
not_null<Data::Feed*> feed,
const style::FeedUserpicButton &st);
private:
struct Part {
not_null<ChannelData*> channel;
base::unique_qptr<UserpicButton> button;
};
void prepare();
void checkParts();
bool partsAreValid() const;
void refreshParts();
QPoint countInnerPosition() const;
const style::FeedUserpicButton &_st;
not_null<Window::Controller*> _controller;
not_null<Data::Feed*> _feed;
std::vector<Part> _parts;
};
class SilentToggle : public Ui::IconButton, public Ui::AbstractTooltipShower {
public:
SilentToggle(QWidget *parent, not_null<ChannelData*> channel);

View File

@ -494,6 +494,13 @@ UserpicButton {
uploadIconPosition: point;
}
FeedUserpicButton {
size: size;
innerSize: pixels;
innerPosition: point;
innerPart: UserpicButton;
}
InfoProfileButton {
textFg: color;
textFgOver: color;
@ -988,6 +995,12 @@ defaultUserpicButton: UserpicButton {
uploadIcon: defaultUploadUserpicIcon;
uploadIconPosition: point(-1px, 1px);
}
defaultFeedUserpicButton: FeedUserpicButton {
size: size(76px, 76px);
innerSize: 76px;
innerPosition: point(-1px, -1px);
innerPart: defaultUserpicButton;
}
historyToDownBelow: icon {
{ "history_down_shadow", historyToDownShadow },