Display common groups in Info profiles.

This commit is contained in:
John Preston 2017-10-10 21:39:44 +01:00
parent fee517384c
commit 583b0fa778
10 changed files with 253 additions and 41 deletions

View File

@ -340,11 +340,11 @@ void PeerListRow::refreshStatus() {
}
}
void PeerListRow::refreshName() {
void PeerListRow::refreshName(const style::PeerListItem &st) {
if (!_initialized) {
return;
}
_name.setText(st::contactsNameStyle, peer()->name, _textNameOptions);
_name.setText(st.nameStyle, peer()->name, _textNameOptions);
}
PeerListRow::~PeerListRow() = default;
@ -457,12 +457,12 @@ float64 PeerListRow::checkedRatio() {
return _checkbox ? _checkbox->checkedAnimationRatio() : 0.;
}
void PeerListRow::lazyInitialize() {
void PeerListRow::lazyInitialize(const style::PeerListItem &st) {
if (_initialized) {
return;
}
_initialized = true;
refreshName();
refreshName(st);
refreshStatus();
}
@ -896,7 +896,7 @@ void PeerListContent::setPressed(Selected pressed) {
void PeerListContent::paintRow(Painter &p, TimeMs ms, RowIndex index) {
auto row = getRow(index);
Assert(row != nullptr);
row->lazyInitialize();
row->lazyInitialize(_st.item);
auto peer = row->peer();
auto user = peer->asUser();
@ -1066,7 +1066,7 @@ void PeerListContent::loadProfilePhotos() {
}
void PeerListContent::checkScrollForPreload() {
if (_visibleBottom + PreloadHeightsCount * (_visibleBottom - _visibleTop) > height()) {
if (_visibleBottom + PreloadHeightsCount * (_visibleBottom - _visibleTop) >= height()) {
_controller->loadMoreRows();
}
}
@ -1295,7 +1295,7 @@ void PeerListContent::handleNameChanged(const Notify::PeerUpdate &update) {
if (addingToSearchIndex()) {
addToSearchIndex(row);
}
row->refreshName();
row->refreshName(_st.item);
updateRow(row);
}
}

View File

@ -101,7 +101,7 @@ public:
virtual void paintAction(Painter &p, TimeMs ms, int x, int y, int outerWidth, bool actionSelected) {
}
void refreshName();
void refreshName(const style::PeerListItem &st);
const Text &name() const {
return _name;
}
@ -166,7 +166,7 @@ public:
return _nameFirstChars;
}
virtual void lazyInitialize();
virtual void lazyInitialize(const style::PeerListItem &st);
virtual void paintStatusText(
Painter &p,
const style::PeerListItem &st,

View File

@ -118,8 +118,8 @@ void PeerListRowWithLink::refreshActionLink() {
_actionWidth = _action.isEmpty() ? 0 : st::normalFont->width(_action);
}
void PeerListRowWithLink::lazyInitialize() {
PeerListRow::lazyInitialize();
void PeerListRowWithLink::lazyInitialize(const style::PeerListItem &st) {
PeerListRow::lazyInitialize(st);
refreshActionLink();
}

View File

@ -47,7 +47,7 @@ public:
void setActionLink(const QString &action);
void lazyInitialize() override;
void lazyInitialize(const style::PeerListItem &st) override;
private:
void refreshActionLink();

View File

@ -352,3 +352,19 @@ infoMediaHeaderPosition: point(14px, 6px);
infoMediaSkip: 6px;
infoMediaMargin: margins(0px, 6px, 0px, 2px);
infoMediaMinGridSize: minPhotoSize;
infoCommonGroupsMargin: margins(0px, 13px, 0px, 2px);
infoCommonGroupsList: PeerList(infoMembersList) {
item: PeerListItem(defaultPeerListItem) {
height: 52px;
photoSize: 40px;
photoPosition: point(16px, 6px);
namePosition: point(71px, 15px);
nameStyle: TextStyle(defaultTextStyle) {
font: font(14px semibold);
linkFont: font(14px semibold);
linkFontOver: font(14px semibold);
}
statusPosition: point(79px, 31px);
}
}

View File

@ -23,20 +23,110 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "info/info_common_groups_widget.h"
#include "lang/lang_keys.h"
#include "styles/style_info.h"
#include "styles/style_widgets.h"
#include "mtproto/sender.h"
#include "window/window_controller.h"
#include "ui/widgets/scroll_area.h"
#include "apiwrap.h"
namespace Info {
namespace CommonGroups {
namespace {
InnerWidget::InnerWidget(QWidget *parent, not_null<UserData*> user)
: RpWidget(parent)
constexpr int kCommonGroupsPerPage = 40;
class Controller
: public PeerListController
, private base::Subscriber
, private MTP::Sender {
public:
Controller(
not_null<Window::Controller*> window,
not_null<UserData*> user);
void prepare() override;
void rowClicked(not_null<PeerListRow*> row) override;
void loadMoreRows() override;
private:
not_null<Window::Controller*> _window;
not_null<UserData*> _user;
mtpRequestId _preloadRequestId = 0;
bool _allLoaded = false;
int32 _preloadGroupId = 0;
};
Controller::Controller(
not_null<Window::Controller*> window,
not_null<UserData*> user)
: PeerListController()
, _window(window)
, _user(user) {
}
void Controller::prepare() {
setSearchNoResultsText(lang(lng_blocked_list_not_found));
delegate()->peerListSetSearchMode(PeerListSearchMode::Enabled);
delegate()->peerListSetTitle(langFactory(lng_profile_common_groups_section));
}
void Controller::loadMoreRows() {
if (_preloadRequestId || _allLoaded) {
return;
}
_preloadRequestId = request(MTPmessages_GetCommonChats(
_user->inputUser,
MTP_int(_preloadGroupId),
MTP_int(kCommonGroupsPerPage)
)).done([this](const MTPmessages_Chats &result) {
_preloadRequestId = 0;
_preloadGroupId = 0;
_allLoaded = true;
if (auto chats = Api::getChatsFromMessagesChats(result)) {
auto &list = chats->v;
if (!list.empty()) {
for_const (auto &chatData, list) {
if (auto chat = App::feedChat(chatData)) {
if (!chat->migrateTo()) {
auto row = std::make_unique<PeerListRow>(chat);
row->setCustomStatus(QString());
delegate()->peerListAppendRow(std::move(row));
}
_preloadGroupId = chat->bareId();
_allLoaded = false;
}
}
delegate()->peerListRefreshRows();
}
}
}).send();
}
void Controller::rowClicked(not_null<PeerListRow*> row) {
_window->showPeerHistory(
row->peer(),
Window::SectionShow::Way::Forward);
}
} // namespace
InnerWidget::InnerWidget(
QWidget *parent,
not_null<Window::Controller*> controller,
not_null<UserData*> user)
: RpWidget(parent)
, _user(user)
, _listController(std::make_unique<Controller>(controller, _user))
, _list(setupList(this, _listController.get())) {
setContent(_list.data());
_listController->setDelegate(static_cast<PeerListDelegate*>(this));
}
void InnerWidget::visibleTopBottomUpdated(
int visibleTop,
int visibleBottom) {
_visibleTop = visibleTop;
_visibleBottom = visibleBottom;
setChildVisibleTopBottom(_list, visibleTop, visibleBottom);
}
void InnerWidget::saveState(not_null<Memento*> memento) {
@ -45,9 +135,81 @@ void InnerWidget::saveState(not_null<Memento*> memento) {
void InnerWidget::restoreState(not_null<Memento*> memento) {
}
int InnerWidget::resizeGetHeight(int newWidth) {
auto rowsHeight = _rowsHeightFake;
return qMax(rowsHeight, _minHeight);
int InnerWidget::desiredHeight() const {
auto desired = 0;
auto count = qMax(_user->commonChatsCount(), 1);
desired += qMax(count, _list->fullRowsCount())
* st::infoCommonGroupsList.item.height;
return qMax(height(), desired);
}
object_ptr<InnerWidget::ListWidget> InnerWidget::setupList(
RpWidget *parent,
not_null<PeerListController*> controller) const {
auto result = object_ptr<ListWidget>(
parent,
controller,
st::infoCommonGroupsList);
result->scrollToRequests()
| rpl::start_with_next([this](Ui::ScrollToRequest request) {
auto addmin = (request.ymin < 0)
? 0
: st::infoCommonGroupsMargin.top();
auto addmax = (request.ymax < 0)
? 0
: st::infoCommonGroupsMargin.top();
_scrollToRequests.fire({
request.ymin + addmin,
request.ymax + addmax });
}, result->lifetime());
result->moveToLeft(0, st::infoCommonGroupsMargin.top());
parent->widthValue()
| rpl::start_with_next([list = result.data()](int newWidth) {
list->resizeToWidth(newWidth);
}, result->lifetime());
result->heightValue()
| rpl::start_with_next([parent](int listHeight) {
auto newHeight = st::infoCommonGroupsMargin.top()
+ listHeight
+ st::infoCommonGroupsMargin.bottom();
parent->resize(parent->width(), newHeight);
}, result->lifetime());
return result;
}
void InnerWidget::peerListSetTitle(base::lambda<QString()> title) {
}
void InnerWidget::peerListSetAdditionalTitle(
base::lambda<QString()> title) {
}
bool InnerWidget::peerListIsRowSelected(not_null<PeerData*> peer) {
return false;
}
int InnerWidget::peerListSelectedRowsCount() {
return 0;
}
std::vector<not_null<PeerData*>> InnerWidget::peerListCollectSelectedRows() {
return {};
}
void InnerWidget::peerListScrollToTop() {
_scrollToRequests.fire({ -1, -1 });
}
void InnerWidget::peerListAddSelectedRowInBunch(not_null<PeerData*> peer) {
Unexpected("Item selection in Info::Profile::Members.");
}
void InnerWidget::peerListFinishSelectedRowsBunch() {
}
void InnerWidget::peerListSetDescription(
object_ptr<Ui::FlatLabel> description) {
description.destroy();
}
} // namespace CommonGroups

View File

@ -22,41 +22,66 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include <rpl/producer.h>
#include "ui/rp_widget.h"
#include "boxes/peer_list_box.h"
namespace Info {
namespace CommonGroups {
class Memento;
class InnerWidget final : public Ui::RpWidget {
class InnerWidget final
: public Ui::RpWidget
, private PeerListContentDelegate {
public:
InnerWidget(QWidget *parent, not_null<UserData*> user);
InnerWidget(
QWidget *parent,
not_null<Window::Controller*> controller,
not_null<UserData*> user);
not_null<UserData*> user() const {
return _user;
}
void resizeToWidth(int newWidth, int minHeight) {
_minHeight = minHeight;
return RpWidget::resizeToWidth(newWidth);
rpl::producer<Ui::ScrollToRequest> scrollToRequests() const {
return _scrollToRequests.events();
}
int desiredHeight() const;
void saveState(not_null<Memento*> memento);
void restoreState(not_null<Memento*> memento);
protected:
int resizeGetHeight(int newWidth) override;
void visibleTopBottomUpdated(
int visibleTop,
int visibleBottom) override;
private:
not_null<UserData*> _user;
using ListWidget = PeerListContent;
int _rowsHeightFake = 0;
int _visibleTop = 0;
int _visibleBottom = 0;
int _minHeight = 0;
// PeerListContentDelegate interface.
void peerListSetTitle(base::lambda<QString()> title) override;
void peerListSetAdditionalTitle(
base::lambda<QString()> title) override;
bool peerListIsRowSelected(not_null<PeerData*> peer) override;
int peerListSelectedRowsCount() override;
std::vector<not_null<PeerData*>> peerListCollectSelectedRows() override;
void peerListScrollToTop() override;
void peerListAddSelectedRowInBunch(
not_null<PeerData*> peer) override;
void peerListFinishSelectedRowsBunch() override;
void peerListSetDescription(
object_ptr<Ui::FlatLabel> description) override;
object_ptr<ListWidget> setupList(
RpWidget *parent,
not_null<PeerListController*> controller) const;
not_null<UserData*> _user;
std::unique_ptr<PeerListController> _listController;
object_ptr<ListWidget> _list;
rpl::event_stream<Ui::ScrollToRequest> _scrollToRequests;
};

View File

@ -46,7 +46,10 @@ Widget::Widget(
not_null<Window::Controller*> controller,
not_null<UserData*> user)
: ContentWidget(parent, wrap, controller, user) {
_inner = setInnerWidget(object_ptr<InnerWidget>(this, user));
_inner = setInnerWidget(object_ptr<InnerWidget>(
this,
controller,
user));
}
not_null<UserData*> Widget::user() const {

View File

@ -144,6 +144,16 @@ void Members::setupButtons() {
this,
st::infoIconMembers,
st::infoIconPosition)->lower();
connect(_searchField, &Ui::FlatInput::cancelled, this, [this] {
cancelSearch();
});
connect(_searchField, &Ui::FlatInput::changed, this, [this] {
applySearch();
});
connect(_searchField, &Ui::FlatInput::submitted, this, [this] {
forceSearchSubmit();
});
}
object_ptr<Members::ListWidget> Members::setupList(
@ -213,15 +223,6 @@ int Members::resizeGetHeight(int newWidth) {
st::infoMembersSearchTop,
cancelLeft - fieldLeft,
_searchField->height());
connect(_searchField, &Ui::FlatInput::cancelled, this, [this] {
cancelSearch();
});
connect(_searchField, &Ui::FlatInput::changed, this, [this] {
applySearch();
});
connect(_searchField, &Ui::FlatInput::submitted, this, [this] {
forceSearchSubmit();
});
_labelWrap->resize(
searchCurrentLeft - st::infoBlockHeaderPosition.x(),
@ -356,7 +357,6 @@ void Members::peerListSetDescription(
description.destroy();
}
} // namespace Profile
} // namespace Info

View File

@ -1058,6 +1058,7 @@ PeerListItem {
height: pixels;
photoPosition: point;
namePosition: point;
nameStyle: TextStyle;
statusPosition: point;
photoSize: pixels;
maximalWidth: pixels;
@ -1092,6 +1093,11 @@ defaultPeerListItem: PeerListItem {
height: 58px;
photoPosition: point(12px, 6px);
namePosition: point(68px, 11px);
nameStyle: TextStyle(defaultTextStyle) {
font: semiboldFont;
linkFont: semiboldFont;
linkFontOver: semiboldFont;
}
statusPosition: point(68px, 31px);
photoSize: 46px;
button: defaultPeerListButton;