mirror of https://github.com/procxx/kepka.git
Allow showing chat members in a special section.
This commit is contained in:
parent
747ebd2136
commit
bef87c6dff
|
@ -186,6 +186,7 @@ InnerWidget::InnerWidget(
|
||||||
, _list(setupList(this, _listController.get())) {
|
, _list(setupList(this, _listController.get())) {
|
||||||
setContent(_list.data());
|
setContent(_list.data());
|
||||||
_listController->setDelegate(static_cast<PeerListDelegate*>(this));
|
_listController->setDelegate(static_cast<PeerListDelegate*>(this));
|
||||||
|
|
||||||
_controller->searchFieldController()->queryValue()
|
_controller->searchFieldController()->queryValue()
|
||||||
| rpl::start_with_next([this](QString &&query) {
|
| rpl::start_with_next([this](QString &&query) {
|
||||||
peerListScrollToTop();
|
peerListScrollToTop();
|
||||||
|
|
|
@ -83,7 +83,9 @@ bool Widget::showInternal(not_null<ContentMemento*> memento) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::setInternalState(const QRect &geometry, not_null<Memento*> memento) {
|
void Widget::setInternalState(
|
||||||
|
const QRect &geometry,
|
||||||
|
not_null<Memento*> memento) {
|
||||||
setGeometry(geometry);
|
setGeometry(geometry);
|
||||||
myEnsureResized(this);
|
myEnsureResized(this);
|
||||||
restoreState(memento);
|
restoreState(memento);
|
||||||
|
|
|
@ -450,20 +450,7 @@ infoMembersSearchActiveLayer: icon {
|
||||||
infoMembersButtonIconPosition
|
infoMembersButtonIconPosition
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
infoMembersSearchField: FlatInput(defaultFlatInput) {
|
infoMembersSearchField: InputField(contactsSearchField) {
|
||||||
textColor: windowFg;
|
|
||||||
bgColor: topBarBg;
|
|
||||||
bgActive: topBarBg;
|
|
||||||
|
|
||||||
font: font(fsize);
|
|
||||||
|
|
||||||
borderWidth: 0px;
|
|
||||||
borderColor: topBarBg;
|
|
||||||
borderActive: topBarBg;
|
|
||||||
|
|
||||||
width: 100px;
|
|
||||||
height: 32px;
|
|
||||||
textMrg: margins(0px, 0px, 0px, 0px);
|
|
||||||
}
|
}
|
||||||
infoMembersCancelSearch: CrossButton {
|
infoMembersCancelSearch: CrossButton {
|
||||||
width: 44px;
|
width: 44px;
|
||||||
|
|
|
@ -28,11 +28,13 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
#include "ui/search_field_controller.h"
|
#include "ui/search_field_controller.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "info/profile/info_profile_widget.h"
|
#include "info/profile/info_profile_widget.h"
|
||||||
|
#include "info/profile/info_profile_members.h"
|
||||||
#include "info/media/info_media_widget.h"
|
#include "info/media/info_media_widget.h"
|
||||||
#include "info/common_groups/info_common_groups_widget.h"
|
#include "info/common_groups/info_common_groups_widget.h"
|
||||||
#include "info/info_layer_widget.h"
|
#include "info/info_layer_widget.h"
|
||||||
#include "info/info_section_widget.h"
|
#include "info/info_section_widget.h"
|
||||||
#include "info/info_controller.h"
|
#include "info/info_controller.h"
|
||||||
|
#include "boxes/peer_list_box.h"
|
||||||
#include "styles/style_info.h"
|
#include "styles/style_info.h"
|
||||||
#include "styles/style_profile.h"
|
#include "styles/style_profile.h"
|
||||||
|
|
||||||
|
@ -54,6 +56,7 @@ ContentWidget::ContentWidget(
|
||||||
: st::profileBg;
|
: st::profileBg;
|
||||||
update();
|
update();
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
|
if (_controller->section().type() != Section::Type::Profile) {
|
||||||
rpl::combine(
|
rpl::combine(
|
||||||
_controller->wrapValue(),
|
_controller->wrapValue(),
|
||||||
_controller->searchEnabledByContent(),
|
_controller->searchEnabledByContent(),
|
||||||
|
@ -61,6 +64,7 @@ ContentWidget::ContentWidget(
|
||||||
| rpl::start_with_next([this](bool shown) {
|
| rpl::start_with_next([this](bool shown) {
|
||||||
refreshSearchField(shown);
|
refreshSearchField(shown);
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
|
}
|
||||||
_scrollTopSkip.changes()
|
_scrollTopSkip.changes()
|
||||||
| rpl::start_with_next([this] {
|
| rpl::start_with_next([this] {
|
||||||
updateControlsGeometry();
|
updateControlsGeometry();
|
||||||
|
@ -211,8 +215,10 @@ void ContentWidget::refreshSearchField(bool shown) {
|
||||||
field->moveToLeft(0, 0);
|
field->moveToLeft(0, 0);
|
||||||
}, field->lifetime());
|
}, field->lifetime());
|
||||||
field->show();
|
field->show();
|
||||||
|
field->setFocus();
|
||||||
setScrollTopSkip(field->heightNoMargins() - st::lineWidth);
|
setScrollTopSkip(field->heightNoMargins() - st::lineWidth);
|
||||||
} else {
|
} else {
|
||||||
|
setFocus();
|
||||||
_searchField = nullptr;
|
_searchField = nullptr;
|
||||||
setScrollTopSkip(0);
|
setScrollTopSkip(0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,14 +102,18 @@ void Controller::setSection(not_null<ContentMemento*> memento) {
|
||||||
|
|
||||||
void Controller::updateSearchControllers(
|
void Controller::updateSearchControllers(
|
||||||
not_null<ContentMemento*> memento) {
|
not_null<ContentMemento*> memento) {
|
||||||
auto isMedia = (_section.type() == Section::Type::Media);
|
using Type = Section::Type;
|
||||||
|
auto type = _section.type();
|
||||||
|
auto isMedia = (type == Type::Media);
|
||||||
auto mediaType = isMedia
|
auto mediaType = isMedia
|
||||||
? _section.mediaType()
|
? _section.mediaType()
|
||||||
: Section::MediaType::kCount;
|
: Section::MediaType::kCount;
|
||||||
auto hasMediaSearch = isMedia
|
auto hasMediaSearch = isMedia
|
||||||
&& SharedMediaAllowSearch(mediaType);
|
&& SharedMediaAllowSearch(mediaType);
|
||||||
auto hasCommonGroupsSearch
|
auto hasCommonGroupsSearch
|
||||||
= (_section.type() == Section::Type::CommonGroups);
|
= (type == Type::CommonGroups);
|
||||||
|
auto hasMembersSearch
|
||||||
|
= (type == Type::Members || type == Type::Profile);
|
||||||
auto searchQuery = memento->searchFieldQuery();
|
auto searchQuery = memento->searchFieldQuery();
|
||||||
if (isMedia) {
|
if (isMedia) {
|
||||||
_searchController
|
_searchController
|
||||||
|
@ -121,7 +125,7 @@ void Controller::updateSearchControllers(
|
||||||
} else {
|
} else {
|
||||||
_searchController = nullptr;
|
_searchController = nullptr;
|
||||||
}
|
}
|
||||||
if (hasMediaSearch || hasCommonGroupsSearch) {
|
if (hasMediaSearch || hasCommonGroupsSearch || hasMembersSearch) {
|
||||||
_searchFieldController
|
_searchFieldController
|
||||||
= std::make_unique<Ui::SearchFieldController>(
|
= std::make_unique<Ui::SearchFieldController>(
|
||||||
searchQuery);
|
searchQuery);
|
||||||
|
|
|
@ -44,6 +44,7 @@ public:
|
||||||
Profile,
|
Profile,
|
||||||
Media,
|
Media,
|
||||||
CommonGroups,
|
CommonGroups,
|
||||||
|
Members,
|
||||||
};
|
};
|
||||||
using MediaType = Storage::SharedMediaType;
|
using MediaType = Storage::SharedMediaType;
|
||||||
|
|
||||||
|
|
|
@ -21,11 +21,14 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
#include "info/info_memento.h"
|
#include "info/info_memento.h"
|
||||||
|
|
||||||
#include "info/profile/info_profile_widget.h"
|
#include "info/profile/info_profile_widget.h"
|
||||||
|
#include "info/profile/info_profile_members.h"
|
||||||
#include "info/media/info_media_widget.h"
|
#include "info/media/info_media_widget.h"
|
||||||
|
#include "info/members/info_members_widget.h"
|
||||||
#include "info/common_groups/info_common_groups_widget.h"
|
#include "info/common_groups/info_common_groups_widget.h"
|
||||||
#include "info/info_section_widget.h"
|
#include "info/info_section_widget.h"
|
||||||
#include "info/info_layer_widget.h"
|
#include "info/info_layer_widget.h"
|
||||||
#include "info/info_controller.h"
|
#include "info/info_controller.h"
|
||||||
|
#include "boxes/peer_list_box.h"
|
||||||
|
|
||||||
namespace Info {
|
namespace Info {
|
||||||
|
|
||||||
|
@ -76,6 +79,10 @@ std::unique_ptr<ContentMemento> Memento::Default(
|
||||||
Assert(peerIsUser(peerId));
|
Assert(peerIsUser(peerId));
|
||||||
return std::make_unique<CommonGroups::Memento>(
|
return std::make_unique<CommonGroups::Memento>(
|
||||||
peerToUser(peerId));
|
peerToUser(peerId));
|
||||||
|
case Section::Type::Members:
|
||||||
|
return std::make_unique<Members::Memento>(
|
||||||
|
peerId,
|
||||||
|
migratedPeerId);
|
||||||
}
|
}
|
||||||
Unexpected("Wrong section type in Info::Memento::Default()");
|
Unexpected("Wrong section type in Info::Memento::Default()");
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "info/info_wrap_widget.h"
|
#include "info/info_wrap_widget.h"
|
||||||
#include "info/info_controller.h"
|
#include "info/info_controller.h"
|
||||||
|
#include "info/profile/info_profile_values.h"
|
||||||
#include "storage/storage_shared_media.h"
|
#include "storage/storage_shared_media.h"
|
||||||
#include "ui/widgets/buttons.h"
|
#include "ui/widgets/buttons.h"
|
||||||
#include "ui/widgets/labels.h"
|
#include "ui/widgets/labels.h"
|
||||||
|
@ -111,6 +112,9 @@ void TopBar::createSearchView(
|
||||||
_st.searchRow.fieldCancel);
|
_st.searchRow.fieldCancel);
|
||||||
|
|
||||||
auto toggleSearchMode = [=](bool enabled, anim::type animated) {
|
auto toggleSearchMode = [=](bool enabled, anim::type animated) {
|
||||||
|
if (!enabled) {
|
||||||
|
setFocus();
|
||||||
|
}
|
||||||
if (_title) {
|
if (_title) {
|
||||||
_title->setVisible(!enabled);
|
_title->setVisible(!enabled);
|
||||||
}
|
}
|
||||||
|
@ -120,6 +124,9 @@ void TopBar::createSearchView(
|
||||||
cancel->finishAnimations();
|
cancel->finishAnimations();
|
||||||
}
|
}
|
||||||
search->toggle(!enabled, animated);
|
search->toggle(!enabled, animated);
|
||||||
|
if (enabled) {
|
||||||
|
field->setFocus();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
auto cancelSearch = [=] {
|
auto cancelSearch = [=] {
|
||||||
|
@ -160,7 +167,6 @@ void TopBar::createSearchView(
|
||||||
|
|
||||||
search->entity()->addClickHandler([=] {
|
search->entity()->addClickHandler([=] {
|
||||||
toggleSearchMode(true, anim::type::normal);
|
toggleSearchMode(true, anim::type::normal);
|
||||||
field->setFocus();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
field->alive()
|
field->alive()
|
||||||
|
@ -248,6 +254,12 @@ void TopBar::startHighlightAnimation() {
|
||||||
rpl::producer<QString> TitleValue(
|
rpl::producer<QString> TitleValue(
|
||||||
const Section §ion,
|
const Section §ion,
|
||||||
not_null<PeerData*> peer) {
|
not_null<PeerData*> peer) {
|
||||||
|
if (section.type() == Section::Type::Members) {
|
||||||
|
return Profile::MembersCountValue(peer)
|
||||||
|
| rpl::map([](int count) {
|
||||||
|
return lng_chat_status_members(lt_count, count);
|
||||||
|
});
|
||||||
|
}
|
||||||
return Lang::Viewer([&] {
|
return Lang::Viewer([&] {
|
||||||
switch (section.type()) {
|
switch (section.type()) {
|
||||||
case Section::Type::Profile:
|
case Section::Type::Profile:
|
||||||
|
|
|
@ -23,6 +23,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
#include <rpl/flatten_latest.h>
|
#include <rpl/flatten_latest.h>
|
||||||
#include <rpl/combine.h>
|
#include <rpl/combine.h>
|
||||||
#include "info/profile/info_profile_widget.h"
|
#include "info/profile/info_profile_widget.h"
|
||||||
|
#include "info/profile/info_profile_members.h"
|
||||||
#include "info/profile/info_profile_values.h"
|
#include "info/profile/info_profile_values.h"
|
||||||
#include "info/media/info_media_widget.h"
|
#include "info/media/info_media_widget.h"
|
||||||
#include "info/info_content_widget.h"
|
#include "info/info_content_widget.h"
|
||||||
|
@ -39,6 +40,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
#include "window/window_controller.h"
|
#include "window/window_controller.h"
|
||||||
#include "window/window_slide_animation.h"
|
#include "window/window_slide_animation.h"
|
||||||
#include "window/window_peer_menu.h"
|
#include "window/window_peer_menu.h"
|
||||||
|
#include "boxes/peer_list_box.h"
|
||||||
#include "auth_session.h"
|
#include "auth_session.h"
|
||||||
#include "mainwidget.h"
|
#include "mainwidget.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
|
@ -261,6 +263,7 @@ void WrapWidget::forceContentRepaint() {
|
||||||
// }
|
// }
|
||||||
// break;
|
// break;
|
||||||
// case Section::Type::CommonGroups:
|
// case Section::Type::CommonGroups:
|
||||||
|
// case Section::Type::Members:
|
||||||
// setupTabs(Tab::None);
|
// setupTabs(Tab::None);
|
||||||
// break;
|
// break;
|
||||||
// }
|
// }
|
||||||
|
@ -482,7 +485,8 @@ void WrapWidget::createTopBarOverride(SelectedItems &&items) {
|
||||||
bool WrapWidget::requireTopBarSearch() const {
|
bool WrapWidget::requireTopBarSearch() const {
|
||||||
if (!_controller->searchFieldController()) {
|
if (!_controller->searchFieldController()) {
|
||||||
return false;
|
return false;
|
||||||
} else if (_controller->wrap() == Wrap::Layer) {
|
} else if (_controller->wrap() == Wrap::Layer
|
||||||
|
|| _controller->section().type() == Section::Type::Profile) {
|
||||||
return false;
|
return false;
|
||||||
} else if (hasStackHistory()) {
|
} else if (hasStackHistory()) {
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -114,7 +114,9 @@ bool Widget::showInternal(not_null<ContentMemento*> memento) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::setInternalState(const QRect &geometry, not_null<Memento*> memento) {
|
void Widget::setInternalState(
|
||||||
|
const QRect &geometry,
|
||||||
|
not_null<Memento*> memento) {
|
||||||
setGeometry(geometry);
|
setGeometry(geometry);
|
||||||
myEnsureResized(this);
|
myEnsureResized(this);
|
||||||
restoreState(memento);
|
restoreState(memento);
|
||||||
|
|
|
@ -0,0 +1,111 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||||
|
|
||||||
|
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
It is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
In addition, as a special exception, the copyright holders give permission
|
||||||
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
|
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
|
*/
|
||||||
|
#include "info/members/info_members_widget.h"
|
||||||
|
|
||||||
|
#include "info/profile/info_profile_members.h"
|
||||||
|
#include "info/info_controller.h"
|
||||||
|
#include "ui/search_field_controller.h"
|
||||||
|
#include "ui/widgets/scroll_area.h"
|
||||||
|
#include "styles/style_info.h"
|
||||||
|
|
||||||
|
namespace Info {
|
||||||
|
namespace Members {
|
||||||
|
|
||||||
|
Memento::Memento(not_null<Controller*> controller)
|
||||||
|
: Memento(
|
||||||
|
controller->peerId(),
|
||||||
|
controller->migratedPeerId()) {
|
||||||
|
}
|
||||||
|
|
||||||
|
Section Memento::section() const {
|
||||||
|
return Section(Section::Type::Members);
|
||||||
|
}
|
||||||
|
|
||||||
|
object_ptr<ContentWidget> Memento::createWidget(
|
||||||
|
QWidget *parent,
|
||||||
|
not_null<Controller*> controller,
|
||||||
|
const QRect &geometry) {
|
||||||
|
auto result = object_ptr<Widget>(
|
||||||
|
parent,
|
||||||
|
controller);
|
||||||
|
result->setInternalState(geometry, this);
|
||||||
|
return std::move(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Memento::setState(std::unique_ptr<SavedState> state) {
|
||||||
|
_state = std::move(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<SavedState> Memento::state() {
|
||||||
|
return std::move(_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
Memento::~Memento() = default;
|
||||||
|
|
||||||
|
Widget::Widget(
|
||||||
|
QWidget *parent,
|
||||||
|
not_null<Controller*> controller)
|
||||||
|
: ContentWidget(parent, controller) {
|
||||||
|
_inner = setInnerWidget(object_ptr<Profile::Members>(
|
||||||
|
this,
|
||||||
|
controller,
|
||||||
|
controller->peer()));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Widget::showInternal(not_null<ContentMemento*> memento) {
|
||||||
|
if (!controller()->validateMementoPeer(memento)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (auto membersMemento = dynamic_cast<Memento*>(memento.get())) {
|
||||||
|
restoreState(membersMemento);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::setInternalState(
|
||||||
|
const QRect &geometry,
|
||||||
|
not_null<Memento*> memento) {
|
||||||
|
setGeometry(geometry);
|
||||||
|
myEnsureResized(this);
|
||||||
|
restoreState(memento);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<ContentMemento> Widget::doCreateMemento() {
|
||||||
|
auto result = std::make_unique<Memento>(controller());
|
||||||
|
saveState(result.get());
|
||||||
|
return std::move(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::saveState(not_null<Memento*> memento) {
|
||||||
|
memento->setScrollTop(scrollTopSave());
|
||||||
|
memento->setState(_inner->saveState());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::restoreState(not_null<Memento*> memento) {
|
||||||
|
_inner->restoreState(memento->state());
|
||||||
|
auto scrollTop = memento->scrollTop();
|
||||||
|
scrollTopRestore(memento->scrollTop());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Members
|
||||||
|
} // namespace Info
|
||||||
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||||
|
|
||||||
|
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
It is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
In addition, as a special exception, the copyright holders give permission
|
||||||
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
|
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <rpl/producer.h>
|
||||||
|
#include "info/info_content_widget.h"
|
||||||
|
|
||||||
|
struct PeerListState;
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class SearchFieldController;
|
||||||
|
} // namespace Ui
|
||||||
|
|
||||||
|
namespace Info {
|
||||||
|
namespace Profile {
|
||||||
|
class Members;
|
||||||
|
struct MembersState;
|
||||||
|
} // namespace Profile
|
||||||
|
|
||||||
|
namespace Members {
|
||||||
|
|
||||||
|
using SavedState = Profile::MembersState;
|
||||||
|
|
||||||
|
class Memento final : public ContentMemento {
|
||||||
|
public:
|
||||||
|
Memento(not_null<Controller*> controller);
|
||||||
|
Memento(PeerId peerId, PeerId migratedPeerId)
|
||||||
|
: ContentMemento(peerId, migratedPeerId) {
|
||||||
|
}
|
||||||
|
|
||||||
|
object_ptr<ContentWidget> createWidget(
|
||||||
|
QWidget *parent,
|
||||||
|
not_null<Controller*> controller,
|
||||||
|
const QRect &geometry) override;
|
||||||
|
|
||||||
|
Section section() const override;
|
||||||
|
|
||||||
|
void setState(std::unique_ptr<SavedState> state);
|
||||||
|
std::unique_ptr<SavedState> state();
|
||||||
|
|
||||||
|
~Memento();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unique_ptr<SavedState> _state;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class Widget final : public ContentWidget {
|
||||||
|
public:
|
||||||
|
Widget(
|
||||||
|
QWidget *parent,
|
||||||
|
not_null<Controller*> controller);
|
||||||
|
|
||||||
|
bool showInternal(
|
||||||
|
not_null<ContentMemento*> memento) override;
|
||||||
|
|
||||||
|
void setInternalState(
|
||||||
|
const QRect &geometry,
|
||||||
|
not_null<Memento*> memento);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void saveState(not_null<Memento*> memento);
|
||||||
|
void restoreState(not_null<Memento*> memento);
|
||||||
|
|
||||||
|
std::unique_ptr<ContentMemento> doCreateMemento() override;
|
||||||
|
|
||||||
|
Profile::Members *_inner = nullptr;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Members
|
||||||
|
} // namespace Info
|
||||||
|
|
|
@ -249,14 +249,14 @@ void InnerWidget::visibleTopBottomUpdated(
|
||||||
void InnerWidget::saveState(not_null<Memento*> memento) {
|
void InnerWidget::saveState(not_null<Memento*> memento) {
|
||||||
memento->setInfoExpanded(_cover->toggled());
|
memento->setInfoExpanded(_cover->toggled());
|
||||||
if (_members) {
|
if (_members) {
|
||||||
_members->saveState(memento);
|
memento->setMembersState(_members->saveState());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void InnerWidget::restoreState(not_null<Memento*> memento) {
|
void InnerWidget::restoreState(not_null<Memento*> memento) {
|
||||||
_cover->toggle(memento->infoExpanded(), anim::type::instant);
|
_cover->toggle(memento->infoExpanded(), anim::type::instant);
|
||||||
if (_members) {
|
if (_members) {
|
||||||
_members->restoreState(memento);
|
_members->restoreState(memento->membersState());
|
||||||
}
|
}
|
||||||
if (_infoWrap) {
|
if (_infoWrap) {
|
||||||
_infoWrap->finishAnimating();
|
_infoWrap->finishAnimating();
|
||||||
|
|
|
@ -28,15 +28,19 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
#include "info/profile/info_profile_members_controllers.h"
|
#include "info/profile/info_profile_members_controllers.h"
|
||||||
#include "info/info_content_widget.h"
|
#include "info/info_content_widget.h"
|
||||||
#include "info/info_controller.h"
|
#include "info/info_controller.h"
|
||||||
|
#include "info/info_memento.h"
|
||||||
#include "ui/widgets/labels.h"
|
#include "ui/widgets/labels.h"
|
||||||
#include "ui/widgets/buttons.h"
|
#include "ui/widgets/buttons.h"
|
||||||
#include "ui/widgets/input_fields.h"
|
#include "ui/widgets/input_fields.h"
|
||||||
#include "ui/widgets/scroll_area.h"
|
#include "ui/widgets/scroll_area.h"
|
||||||
|
#include "ui/wrap/padding_wrap.h"
|
||||||
|
#include "ui/search_field_controller.h"
|
||||||
#include "styles/style_boxes.h"
|
#include "styles/style_boxes.h"
|
||||||
#include "styles/style_info.h"
|
#include "styles/style_info.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "boxes/confirm_box.h"
|
#include "boxes/confirm_box.h"
|
||||||
#include "boxes/peer_list_controllers.h"
|
#include "boxes/peer_list_controllers.h"
|
||||||
|
#include "window/window_controller.h"
|
||||||
|
|
||||||
namespace Info {
|
namespace Info {
|
||||||
namespace Profile {
|
namespace Profile {
|
||||||
|
@ -51,30 +55,23 @@ Members::Members(
|
||||||
not_null<Controller*> controller,
|
not_null<Controller*> controller,
|
||||||
not_null<PeerData*> peer)
|
not_null<PeerData*> peer)
|
||||||
: RpWidget(parent)
|
: RpWidget(parent)
|
||||||
|
, _controller(controller)
|
||||||
, _peer(peer)
|
, _peer(peer)
|
||||||
, _listController(CreateMembersController(controller->window(), _peer))
|
, _listController(CreateMembersController(controller->window(), _peer)) {
|
||||||
, _labelWrap(this)
|
setupHeader();
|
||||||
, _label(setupHeader())
|
setupList();
|
||||||
, _addMember(this, st::infoMembersAddMember)
|
|
||||||
, _searchField(
|
|
||||||
this,
|
|
||||||
st::infoMembersSearchField,
|
|
||||||
langFactory(lng_participant_filter))
|
|
||||||
, _search(this, st::infoMembersSearch)
|
|
||||||
, _cancelSearch(this, st::infoMembersCancelSearch)
|
|
||||||
, _list(setupList(this, _listController.get())) {
|
|
||||||
setupButtons();
|
|
||||||
controller->wrapValue()
|
|
||||||
| rpl::start_with_next([this](Wrap wrap) {
|
|
||||||
_wrap = wrap;
|
|
||||||
updateSearchOverrides();
|
|
||||||
}, lifetime());
|
|
||||||
setContent(_list.data());
|
setContent(_list.data());
|
||||||
_listController->setDelegate(static_cast<PeerListDelegate*>(this));
|
_listController->setDelegate(static_cast<PeerListDelegate*>(this));
|
||||||
|
|
||||||
|
_controller->searchFieldController()->queryValue()
|
||||||
|
| rpl::start_with_next([this](QString &&query) {
|
||||||
|
peerListScrollToTop();
|
||||||
|
content()->searchQueryChanged(std::move(query));
|
||||||
|
}, lifetime());
|
||||||
}
|
}
|
||||||
|
|
||||||
int Members::desiredHeight() const {
|
int Members::desiredHeight() const {
|
||||||
auto desired = st::infoMembersHeader;
|
auto desired = _header ? _header->height() : 0;
|
||||||
auto count = [this] {
|
auto count = [this] {
|
||||||
if (auto chat = _peer->asChat()) {
|
if (auto chat = _peer->asChat()) {
|
||||||
return chat->count;
|
return chat->count;
|
||||||
|
@ -92,30 +89,76 @@ rpl::producer<int> Members::onlineCountValue() const {
|
||||||
return _listController->onlineCountValue();
|
return _listController->onlineCountValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Members::saveState(not_null<Memento*> memento) {
|
std::unique_ptr<MembersState> Members::saveState() {
|
||||||
if (_searchShown) {
|
auto result = std::make_unique<MembersState>();
|
||||||
memento->setMembersSearch(_searchField->getLastText());
|
result->list = _listController->saveState();
|
||||||
}
|
//if (_searchShown) {
|
||||||
memento->setMembersState(_listController->saveState());
|
// result->search = _searchField->getLastText();
|
||||||
|
//}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Members::restoreState(not_null<Memento*> memento) {
|
void Members::restoreState(std::unique_ptr<MembersState> state) {
|
||||||
_listController->restoreState(memento->membersState());
|
if (!state) {
|
||||||
if (auto text = memento->membersSearch()) {
|
return;
|
||||||
if (!_searchShown) {
|
|
||||||
toggleSearch(anim::type::instant);
|
|
||||||
}
|
|
||||||
_searchField->setText(*text);
|
|
||||||
_searchField->updatePlaceholder();
|
|
||||||
applySearch();
|
|
||||||
} else if (_searchShown) {
|
|
||||||
toggleSearch(anim::type::instant);
|
|
||||||
}
|
}
|
||||||
|
_listController->restoreState(std::move(state->list));
|
||||||
|
updateSearchEnabledByContent();
|
||||||
|
//if (!_controller->searchFieldController()->query().isEmpty()) {
|
||||||
|
// if (!_searchShown) {
|
||||||
|
// toggleSearch(anim::type::instant);
|
||||||
|
// }
|
||||||
|
//} else if (_searchShown) {
|
||||||
|
// toggleSearch(anim::type::instant);
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
object_ptr<Ui::FlatLabel> Members::setupHeader() {
|
void Members::setupHeader() {
|
||||||
|
if (_controller->section().type() == Section::Type::Members) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_header = object_ptr<Ui::FixedHeightWidget>(
|
||||||
|
this,
|
||||||
|
st::infoMembersHeader);
|
||||||
|
auto parent = _header.data();
|
||||||
|
|
||||||
|
object_ptr<FloatingIcon>(
|
||||||
|
parent,
|
||||||
|
st::infoIconMembers,
|
||||||
|
st::infoIconPosition);
|
||||||
|
|
||||||
|
_openMembers = Ui::CreateChild<Ui::AbstractButton>(parent);
|
||||||
|
_titleWrap = Ui::CreateChild<Ui::RpWidget>(parent);
|
||||||
|
_title = setupTitle();
|
||||||
|
_addMember = Ui::CreateChild<Ui::IconButton>(
|
||||||
|
parent,
|
||||||
|
st::infoMembersAddMember);
|
||||||
|
//_searchField = _controller->searchFieldController()->createField(
|
||||||
|
// parent,
|
||||||
|
// st::infoMembersSearchField);
|
||||||
|
//_search = Ui::CreateChild<Ui::IconButton>(
|
||||||
|
// parent,
|
||||||
|
// st::infoMembersSearch);
|
||||||
|
//_cancelSearch = Ui::CreateChild<Ui::CrossButton>(
|
||||||
|
// parent,
|
||||||
|
// st::infoMembersCancelSearch);
|
||||||
|
|
||||||
|
setupButtons();
|
||||||
|
|
||||||
|
//_controller->wrapValue()
|
||||||
|
// | rpl::start_with_next([this](Wrap wrap) {
|
||||||
|
// _wrap = wrap;
|
||||||
|
// updateSearchOverrides();
|
||||||
|
// }, lifetime());
|
||||||
|
widthValue()
|
||||||
|
| rpl::start_with_next([this](int width) {
|
||||||
|
_header->resizeToWidth(width);
|
||||||
|
}, _header->lifetime());
|
||||||
|
}
|
||||||
|
|
||||||
|
object_ptr<Ui::FlatLabel> Members::setupTitle() {
|
||||||
auto result = object_ptr<Ui::FlatLabel>(
|
auto result = object_ptr<Ui::FlatLabel>(
|
||||||
_labelWrap,
|
_titleWrap,
|
||||||
MembersCountValue(_peer)
|
MembersCountValue(_peer)
|
||||||
| rpl::map([](int count) {
|
| rpl::map([](int count) {
|
||||||
return lng_chat_status_members(lt_count, count);
|
return lng_chat_status_members(lt_count, count);
|
||||||
|
@ -129,8 +172,14 @@ object_ptr<Ui::FlatLabel> Members::setupHeader() {
|
||||||
void Members::setupButtons() {
|
void Members::setupButtons() {
|
||||||
using namespace rpl::mappers;
|
using namespace rpl::mappers;
|
||||||
|
|
||||||
_searchField->hide();
|
_openMembers->addClickHandler([this] {
|
||||||
_cancelSearch->hideFast();
|
_controller->window()->showSection(Info::Memento(
|
||||||
|
_controller->peerId(),
|
||||||
|
Section::Type::Members));
|
||||||
|
});
|
||||||
|
|
||||||
|
//_searchField->hide();
|
||||||
|
//_cancelSearch->hideFast();
|
||||||
|
|
||||||
auto addMemberShown = CanAddMemberValue(_peer)
|
auto addMemberShown = CanAddMemberValue(_peer)
|
||||||
| rpl::start_spawning(lifetime());
|
| rpl::start_spawning(lifetime());
|
||||||
|
@ -139,128 +188,129 @@ void Members::setupButtons() {
|
||||||
this->addMember();
|
this->addMember();
|
||||||
});
|
});
|
||||||
|
|
||||||
auto searchShown = MembersCountValue(_peer)
|
//auto searchShown = MembersCountValue(_peer)
|
||||||
| rpl::map($1 >= kEnableSearchMembersAfterCount)
|
// | rpl::map($1 >= kEnableSearchMembersAfterCount)
|
||||||
| rpl::distinct_until_changed()
|
// | rpl::distinct_until_changed()
|
||||||
| rpl::start_spawning(lifetime());
|
// | rpl::start_spawning(lifetime());
|
||||||
_search->showOn(rpl::duplicate(searchShown));
|
//_search->showOn(rpl::duplicate(searchShown));
|
||||||
_search->addClickHandler([this] {
|
//_search->addClickHandler([this] {
|
||||||
this->showSearch();
|
// this->showSearch();
|
||||||
});
|
//});
|
||||||
_cancelSearch->addClickHandler([this] {
|
//_cancelSearch->addClickHandler([this] {
|
||||||
this->cancelSearch();
|
// this->cancelSearch();
|
||||||
});
|
//});
|
||||||
|
|
||||||
rpl::combine(
|
//rpl::combine(
|
||||||
std::move(addMemberShown),
|
// std::move(addMemberShown),
|
||||||
std::move(searchShown))
|
// std::move(searchShown))
|
||||||
|
std::move(addMemberShown)
|
||||||
| rpl::start_with_next([this] {
|
| rpl::start_with_next([this] {
|
||||||
this->resizeToWidth(width());
|
updateHeaderControlsGeometry(width());
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
|
|
||||||
object_ptr<FloatingIcon>(
|
|
||||||
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(
|
void Members::setupList() {
|
||||||
RpWidget *parent,
|
auto topSkip = _header ? _header->height() : 0;
|
||||||
not_null<PeerListController*> controller) const {
|
_list = object_ptr<ListWidget>(
|
||||||
auto result = object_ptr<ListWidget>(
|
this,
|
||||||
parent,
|
_listController.get(),
|
||||||
controller,
|
|
||||||
st::infoMembersList);
|
st::infoMembersList);
|
||||||
result->scrollToRequests()
|
_list->scrollToRequests()
|
||||||
| rpl::start_with_next([this](Ui::ScrollToRequest request) {
|
| rpl::start_with_next([this](Ui::ScrollToRequest request) {
|
||||||
auto addmin = (request.ymin < 0)
|
auto addmin = (request.ymin < 0 || !_header)
|
||||||
? 0
|
? 0
|
||||||
: st::infoMembersHeader;
|
: _header->height();
|
||||||
auto addmax = (request.ymax < 0)
|
auto addmax = (request.ymax < 0 || !_header)
|
||||||
? 0
|
? 0
|
||||||
: st::infoMembersHeader;
|
: _header->height();
|
||||||
_scrollToRequests.fire({
|
_scrollToRequests.fire({
|
||||||
request.ymin + addmin,
|
request.ymin + addmin,
|
||||||
request.ymax + addmax });
|
request.ymax + addmax });
|
||||||
}, result->lifetime());
|
}, _list->lifetime());
|
||||||
result->moveToLeft(0, st::infoMembersHeader);
|
widthValue()
|
||||||
parent->widthValue()
|
| rpl::start_with_next([this](int newWidth) {
|
||||||
| rpl::start_with_next([list = result.data()](int newWidth) {
|
_list->resizeToWidth(newWidth);
|
||||||
list->resizeToWidth(newWidth);
|
}, _list->lifetime());
|
||||||
}, result->lifetime());
|
_list->heightValue()
|
||||||
result->heightValue()
|
| rpl::start_with_next([=](int listHeight) {
|
||||||
| rpl::start_with_next([parent](int listHeight) {
|
|
||||||
auto newHeight = (listHeight > st::membersMarginBottom)
|
auto newHeight = (listHeight > st::membersMarginBottom)
|
||||||
? (st::infoMembersHeader
|
? (topSkip
|
||||||
+ listHeight
|
+ listHeight
|
||||||
+ st::membersMarginBottom)
|
+ st::membersMarginBottom)
|
||||||
: 0;
|
: 0;
|
||||||
parent->resize(parent->width(), newHeight);
|
resize(width(), newHeight);
|
||||||
}, result->lifetime());
|
}, _list->lifetime());
|
||||||
return result;
|
_list->moveToLeft(0, topSkip);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Members::resizeGetHeight(int newWidth) {
|
int Members::resizeGetHeight(int newWidth) {
|
||||||
|
if (_header) {
|
||||||
|
updateHeaderControlsGeometry(newWidth);
|
||||||
|
}
|
||||||
|
return heightNoMargins();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Members::updateSearchEnabledByContent() {
|
||||||
|
_controller->setSearchEnabledByContent(
|
||||||
|
peerListFullRowsCount() >= kEnableSearchMembersAfterCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Members::updateHeaderControlsGeometry(int newWidth) {
|
||||||
|
_openMembers->setGeometry(0, 0, newWidth, st::infoMembersHeader);
|
||||||
|
|
||||||
auto availableWidth = newWidth
|
auto availableWidth = newWidth
|
||||||
- st::infoMembersButtonPosition.x();
|
- st::infoMembersButtonPosition.x();
|
||||||
|
|
||||||
auto cancelLeft = availableWidth - _cancelSearch->width();
|
//auto cancelLeft = availableWidth - _cancelSearch->width();
|
||||||
_cancelSearch->moveToLeft(
|
//_cancelSearch->moveToLeft(
|
||||||
cancelLeft,
|
// cancelLeft,
|
||||||
st::infoMembersButtonPosition.y());
|
// st::infoMembersButtonPosition.y());
|
||||||
|
|
||||||
auto searchShownLeft = st::infoIconPosition.x()
|
//auto searchShownLeft = st::infoIconPosition.x()
|
||||||
- st::infoMembersSearch.iconPosition.x();
|
// - st::infoMembersSearch.iconPosition.x();
|
||||||
auto searchHiddenLeft = availableWidth - _search->width();
|
//auto searchHiddenLeft = availableWidth - _search->width();
|
||||||
auto searchShown = _searchShownAnimation.current(_searchShown ? 1. : 0.);
|
//auto searchShown = _searchShownAnimation.current(_searchShown ? 1. : 0.);
|
||||||
auto searchCurrentLeft = anim::interpolate(
|
//auto searchCurrentLeft = anim::interpolate(
|
||||||
searchHiddenLeft,
|
// searchHiddenLeft,
|
||||||
searchShownLeft,
|
// searchShownLeft,
|
||||||
searchShown);
|
// searchShown);
|
||||||
_search->moveToLeft(
|
//_search->moveToLeft(
|
||||||
searchCurrentLeft,
|
// searchCurrentLeft,
|
||||||
st::infoMembersButtonPosition.y());
|
// st::infoMembersButtonPosition.y());
|
||||||
|
|
||||||
if (!_search->isHidden()) {
|
//if (!_search->isHidden()) {
|
||||||
availableWidth -= st::infoMembersSearch.width;
|
// availableWidth -= st::infoMembersSearch.width;
|
||||||
}
|
//}
|
||||||
_addMember->moveToLeft(
|
_addMember->moveToLeft(
|
||||||
availableWidth - _addMember->width(),
|
availableWidth - _addMember->width(),
|
||||||
st::infoMembersButtonPosition.y(),
|
st::infoMembersButtonPosition.y(),
|
||||||
newWidth);
|
newWidth);
|
||||||
|
|
||||||
auto fieldLeft = anim::interpolate(
|
//auto fieldLeft = anim::interpolate(
|
||||||
cancelLeft,
|
// cancelLeft,
|
||||||
st::infoBlockHeaderPosition.x(),
|
// st::infoBlockHeaderPosition.x(),
|
||||||
searchShown);
|
// searchShown);
|
||||||
_searchField->setGeometryToLeft(
|
//_searchField->setGeometryToLeft(
|
||||||
fieldLeft,
|
// fieldLeft,
|
||||||
st::infoMembersSearchTop,
|
// st::infoMembersSearchTop,
|
||||||
cancelLeft - fieldLeft,
|
// cancelLeft - fieldLeft,
|
||||||
_searchField->height());
|
// _searchField->height());
|
||||||
|
|
||||||
_labelWrap->resize(
|
//_titleWrap->resize(
|
||||||
searchCurrentLeft - st::infoBlockHeaderPosition.x(),
|
// searchCurrentLeft - st::infoBlockHeaderPosition.x(),
|
||||||
_label->height());
|
// _title->height());
|
||||||
_labelWrap->moveToLeft(
|
_titleWrap->resize(
|
||||||
|
availableWidth - _addMember->width() - st::infoBlockHeaderPosition.x(),
|
||||||
|
_title->height());
|
||||||
|
_titleWrap->moveToLeft(
|
||||||
st::infoBlockHeaderPosition.x(),
|
st::infoBlockHeaderPosition.x(),
|
||||||
st::infoBlockHeaderPosition.y(),
|
st::infoBlockHeaderPosition.y(),
|
||||||
newWidth);
|
newWidth);
|
||||||
|
_titleWrap->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||||
|
|
||||||
_label->resizeToWidth(searchHiddenLeft);
|
//_title->resizeToWidth(searchHiddenLeft);
|
||||||
_label->moveToLeft(0, 0);
|
_title->resizeToWidth(_titleWrap->width());
|
||||||
|
_title->moveToLeft(0, 0);
|
||||||
return heightNoMargins();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Members::addMember() {
|
void Members::addMember() {
|
||||||
|
@ -278,74 +328,63 @@ void Members::addMember() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Members::showSearch() {
|
//void Members::showSearch() {
|
||||||
if (!_searchShown) {
|
// if (!_searchShown) {
|
||||||
toggleSearch();
|
// toggleSearch();
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
void Members::toggleSearch(anim::type animated) {
|
//void Members::toggleSearch(anim::type animated) {
|
||||||
_searchShown = !_searchShown;
|
// _searchShown = !_searchShown;
|
||||||
if (animated == anim::type::normal) {
|
// if (animated == anim::type::normal) {
|
||||||
_cancelSearch->toggleAnimated(_searchShown);
|
// _cancelSearch->toggleAnimated(_searchShown);
|
||||||
_searchShownAnimation.start(
|
// _searchShownAnimation.start(
|
||||||
[this] { searchAnimationCallback(); },
|
// [this] { searchAnimationCallback(); },
|
||||||
_searchShown ? 0. : 1.,
|
// _searchShown ? 0. : 1.,
|
||||||
_searchShown ? 1. : 0.,
|
// _searchShown ? 1. : 0.,
|
||||||
st::slideWrapDuration);
|
// st::slideWrapDuration);
|
||||||
} else {
|
// } else {
|
||||||
_cancelSearch->toggleFast(_searchShown);
|
// _cancelSearch->toggleFast(_searchShown);
|
||||||
_searchShownAnimation.finish();
|
// _searchShownAnimation.finish();
|
||||||
searchAnimationCallback();
|
// searchAnimationCallback();
|
||||||
}
|
// }
|
||||||
_search->setDisabled(_searchShown);
|
// _search->setDisabled(_searchShown);
|
||||||
if (_searchShown) {
|
// if (_searchShown) {
|
||||||
_searchField->show();
|
// _searchField->show();
|
||||||
_searchField->setFocus();
|
// _searchField->setFocus();
|
||||||
} else {
|
// } else {
|
||||||
setFocus();
|
// setFocus();
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
void Members::searchAnimationCallback() {
|
//void Members::searchAnimationCallback() {
|
||||||
if (!_searchShownAnimation.animating()) {
|
// if (!_searchShownAnimation.animating()) {
|
||||||
_searchField->setVisible(_searchShown);
|
// _searchField->setVisible(_searchShown);
|
||||||
updateSearchOverrides();
|
// updateSearchOverrides();
|
||||||
_search->setPointerCursor(!_searchShown);
|
// _search->setPointerCursor(!_searchShown);
|
||||||
}
|
// }
|
||||||
resizeToWidth(width());
|
// updateHeaderControlsGeometry(width());
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
void Members::updateSearchOverrides() {
|
//void Members::updateSearchOverrides() {
|
||||||
auto iconOverride = !_searchShown
|
// auto iconOverride = !_searchShown
|
||||||
? nullptr
|
// ? nullptr
|
||||||
: (_wrap == Wrap::Layer)
|
// : (_wrap == Wrap::Layer)
|
||||||
? &st::infoMembersSearchActiveLayer
|
// ? &st::infoMembersSearchActiveLayer
|
||||||
: &st::infoMembersSearchActive;
|
// : &st::infoMembersSearchActive;
|
||||||
_search->setIconOverride(iconOverride, iconOverride);
|
// _search->setIconOverride(iconOverride, iconOverride);
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
void Members::cancelSearch() {
|
//void Members::cancelSearch() {
|
||||||
if (_searchShown) {
|
// if (_searchShown) {
|
||||||
if (!_searchField->getLastText().isEmpty()) {
|
// if (!_searchField->getLastText().isEmpty()) {
|
||||||
_searchField->setText(QString());
|
// _searchField->setText(QString());
|
||||||
_searchField->updatePlaceholder();
|
// _searchField->setFocus();
|
||||||
_searchField->setFocus();
|
// } else {
|
||||||
applySearch();
|
// toggleSearch();
|
||||||
} else {
|
// }
|
||||||
toggleSearch();
|
// }
|
||||||
}
|
//}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Members::applySearch() {
|
|
||||||
peerListScrollToTop();
|
|
||||||
content()->searchQueryChanged(_searchField->getLastText());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Members::forceSearchSubmit() {
|
|
||||||
content()->submitted();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Members::visibleTopBottomUpdated(
|
void Members::visibleTopBottomUpdated(
|
||||||
int visibleTop,
|
int visibleTop,
|
||||||
|
|
|
@ -24,11 +24,12 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
#include "boxes/peer_list_box.h"
|
#include "boxes/peer_list_box.h"
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class FlatInput;
|
class InputField;
|
||||||
class CrossButton;
|
class CrossButton;
|
||||||
class IconButton;
|
class IconButton;
|
||||||
class FlatLabel;
|
class FlatLabel;
|
||||||
struct ScrollToRequest;
|
struct ScrollToRequest;
|
||||||
|
class AbstractButton;
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
|
||||||
namespace Profile {
|
namespace Profile {
|
||||||
|
@ -44,6 +45,10 @@ enum class Wrap;
|
||||||
namespace Profile {
|
namespace Profile {
|
||||||
|
|
||||||
class Memento;
|
class Memento;
|
||||||
|
struct MembersState {
|
||||||
|
std::unique_ptr<PeerListState> list;
|
||||||
|
base::optional<QString> search;
|
||||||
|
};
|
||||||
|
|
||||||
class Members
|
class Members
|
||||||
: public Ui::RpWidget
|
: public Ui::RpWidget
|
||||||
|
@ -58,8 +63,8 @@ public:
|
||||||
return _scrollToRequests.events();
|
return _scrollToRequests.events();
|
||||||
}
|
}
|
||||||
|
|
||||||
void saveState(not_null<Memento*> memento);
|
std::unique_ptr<MembersState> saveState();
|
||||||
void restoreState(not_null<Memento*> memento);
|
void restoreState(std::unique_ptr<MembersState> state);
|
||||||
|
|
||||||
int desiredHeight() const;
|
int desiredHeight() const;
|
||||||
rpl::producer<int> onlineCountValue() const;
|
rpl::producer<int> onlineCountValue() const;
|
||||||
|
@ -87,36 +92,54 @@ private:
|
||||||
void peerListSetDescription(
|
void peerListSetDescription(
|
||||||
object_ptr<Ui::FlatLabel> description) override;
|
object_ptr<Ui::FlatLabel> description) override;
|
||||||
|
|
||||||
object_ptr<Ui::FlatLabel> setupHeader();
|
void peerListAppendRow(
|
||||||
object_ptr<ListWidget> setupList(
|
std::unique_ptr<PeerListRow> row) override {
|
||||||
RpWidget *parent,
|
PeerListContentDelegate::peerListAppendRow(std::move(row));
|
||||||
not_null<PeerListController*> controller) const;
|
updateSearchEnabledByContent();
|
||||||
|
}
|
||||||
|
void peerListPrependRow(
|
||||||
|
std::unique_ptr<PeerListRow> row) override {
|
||||||
|
PeerListContentDelegate::peerListPrependRow(std::move(row));
|
||||||
|
updateSearchEnabledByContent();
|
||||||
|
}
|
||||||
|
void peerListRemoveRow(not_null<PeerListRow*> row) override {
|
||||||
|
PeerListContentDelegate::peerListRemoveRow(row);
|
||||||
|
updateSearchEnabledByContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setupHeader();
|
||||||
|
object_ptr<Ui::FlatLabel> setupTitle();
|
||||||
|
void setupList();
|
||||||
|
|
||||||
void setupButtons();
|
void setupButtons();
|
||||||
void updateSearchOverrides();
|
//void updateSearchOverrides();
|
||||||
|
|
||||||
void addMember();
|
void addMember();
|
||||||
void showSearch();
|
//void showSearch();
|
||||||
void toggleSearch(anim::type animated = anim::type::normal);
|
//void toggleSearch(anim::type animated = anim::type::normal);
|
||||||
void cancelSearch();
|
//void cancelSearch();
|
||||||
void applySearch();
|
//void searchAnimationCallback();
|
||||||
void forceSearchSubmit();
|
void updateHeaderControlsGeometry(int newWidth);
|
||||||
void searchAnimationCallback();
|
void updateSearchEnabledByContent();
|
||||||
|
|
||||||
Wrap _wrap;
|
Wrap _wrap;
|
||||||
|
not_null<Controller*> _controller;
|
||||||
not_null<PeerData*> _peer;
|
not_null<PeerData*> _peer;
|
||||||
std::unique_ptr<PeerListController> _listController;
|
std::unique_ptr<PeerListController> _listController;
|
||||||
object_ptr<Ui::RpWidget> _labelWrap;
|
object_ptr<Ui::RpWidget> _header = { nullptr };
|
||||||
object_ptr<Ui::FlatLabel> _label;
|
object_ptr<ListWidget> _list = { nullptr };
|
||||||
object_ptr<Ui::IconButton> _addMember;
|
|
||||||
object_ptr<Ui::FlatInput> _searchField;
|
|
||||||
object_ptr<Ui::IconButton> _search;
|
|
||||||
object_ptr<Ui::CrossButton> _cancelSearch;
|
|
||||||
object_ptr<ListWidget> _list;
|
|
||||||
|
|
||||||
Animation _searchShownAnimation;
|
Ui::AbstractButton *_openMembers = nullptr;
|
||||||
bool _searchShown = false;
|
Ui::RpWidget *_titleWrap = nullptr;
|
||||||
base::Timer _searchTimer;
|
Ui::FlatLabel *_title = nullptr;
|
||||||
|
Ui::IconButton *_addMember = nullptr;
|
||||||
|
//base::unique_qptr<Ui::InputField> _searchField;
|
||||||
|
//Ui::IconButton *_search = nullptr;
|
||||||
|
//Ui::CrossButton *_cancelSearch = nullptr;
|
||||||
|
|
||||||
|
//Animation _searchShownAnimation;
|
||||||
|
//bool _searchShown = false;
|
||||||
|
//base::Timer _searchTimer;
|
||||||
|
|
||||||
rpl::event_stream<Ui::ScrollToRequest> _scrollToRequests;
|
rpl::event_stream<Ui::ScrollToRequest> _scrollToRequests;
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
#include "info/profile/info_profile_widget.h"
|
#include "info/profile/info_profile_widget.h"
|
||||||
|
|
||||||
#include "info/profile/info_profile_inner_widget.h"
|
#include "info/profile/info_profile_inner_widget.h"
|
||||||
|
#include "info/profile/info_profile_members.h"
|
||||||
#include "ui/widgets/scroll_area.h"
|
#include "ui/widgets/scroll_area.h"
|
||||||
#include "info/info_controller.h"
|
#include "info/info_controller.h"
|
||||||
|
|
||||||
|
@ -48,10 +49,22 @@ object_ptr<ContentWidget> Memento::createWidget(
|
||||||
return std::move(result);
|
return std::move(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Memento::setMembersState(std::unique_ptr<MembersState> state) {
|
||||||
|
_membersState = std::move(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<MembersState> Memento::membersState() {
|
||||||
|
return std::move(_membersState);
|
||||||
|
}
|
||||||
|
|
||||||
|
Memento::~Memento() = default;
|
||||||
|
|
||||||
Widget::Widget(
|
Widget::Widget(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
not_null<Controller*> controller)
|
not_null<Controller*> controller)
|
||||||
: ContentWidget(parent, controller) {
|
: ContentWidget(parent, controller) {
|
||||||
|
controller->setSearchEnabledByContent(false);
|
||||||
|
|
||||||
_inner = setInnerWidget(object_ptr<InnerWidget>(
|
_inner = setInnerWidget(object_ptr<InnerWidget>(
|
||||||
this,
|
this,
|
||||||
controller));
|
controller));
|
||||||
|
@ -86,7 +99,9 @@ bool Widget::showInternal(not_null<ContentMemento*> memento) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::setInternalState(const QRect &geometry, not_null<Memento*> memento) {
|
void Widget::setInternalState(
|
||||||
|
const QRect &geometry,
|
||||||
|
not_null<Memento*> memento) {
|
||||||
setGeometry(geometry);
|
setGeometry(geometry);
|
||||||
myEnsureResized(this);
|
myEnsureResized(this);
|
||||||
restoreState(memento);
|
restoreState(memento);
|
||||||
|
|
|
@ -22,12 +22,12 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
#include <rpl/producer.h>
|
#include <rpl/producer.h>
|
||||||
#include "info/info_content_widget.h"
|
#include "info/info_content_widget.h"
|
||||||
#include "boxes/peer_list_box.h"
|
|
||||||
|
|
||||||
namespace Info {
|
namespace Info {
|
||||||
namespace Profile {
|
namespace Profile {
|
||||||
|
|
||||||
class InnerWidget;
|
class InnerWidget;
|
||||||
|
struct MembersState;
|
||||||
|
|
||||||
class Memento final : public ContentMemento {
|
class Memento final : public ContentMemento {
|
||||||
public:
|
public:
|
||||||
|
@ -49,23 +49,15 @@ public:
|
||||||
bool infoExpanded() const {
|
bool infoExpanded() const {
|
||||||
return _infoExpanded;
|
return _infoExpanded;
|
||||||
}
|
}
|
||||||
void setMembersSearch(QString query) {
|
void setMembersState(std::unique_ptr<MembersState> state);
|
||||||
_membersSearch = query;
|
std::unique_ptr<MembersState> membersState();
|
||||||
}
|
|
||||||
base::optional<QString> membersSearch() const {
|
~Memento();
|
||||||
return _membersSearch;
|
|
||||||
}
|
|
||||||
void setMembersState(std::unique_ptr<PeerListState> state) {
|
|
||||||
_membersState = std::move(state);
|
|
||||||
}
|
|
||||||
std::unique_ptr<PeerListState> membersState() {
|
|
||||||
return std::move(_membersState);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _infoExpanded = true;
|
bool _infoExpanded = true;
|
||||||
base::optional<QString> _membersSearch;
|
base::optional<QString> _membersSearch;
|
||||||
std::unique_ptr<PeerListState> _membersState;
|
std::unique_ptr<MembersState> _membersState;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -248,6 +248,8 @@
|
||||||
<(src_loc)/info/media/info_media_list_widget.h
|
<(src_loc)/info/media/info_media_list_widget.h
|
||||||
<(src_loc)/info/media/info_media_widget.cpp
|
<(src_loc)/info/media/info_media_widget.cpp
|
||||||
<(src_loc)/info/media/info_media_widget.h
|
<(src_loc)/info/media/info_media_widget.h
|
||||||
|
<(src_loc)/info/members/info_members_widget.cpp
|
||||||
|
<(src_loc)/info/members/info_members_widget.h
|
||||||
<(src_loc)/info/profile/info_profile_actions.cpp
|
<(src_loc)/info/profile/info_profile_actions.cpp
|
||||||
<(src_loc)/info/profile/info_profile_actions.h
|
<(src_loc)/info/profile/info_profile_actions.h
|
||||||
<(src_loc)/info/profile/info_profile_button.cpp
|
<(src_loc)/info/profile/info_profile_button.cpp
|
||||||
|
|
Loading…
Reference in New Issue