mirror of https://github.com/procxx/kepka.git
Improve empty chat list layout.
This commit is contained in:
parent
9ef41062d3
commit
69d3414594
|
@ -87,6 +87,14 @@ dialogsTextPaletteArchiveActive: TextPalette(defaultTextPalette) {
|
||||||
linkFg: dialogsTextFgActive;
|
linkFg: dialogsTextFgActive;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dialogsEmptyHeight: 160px;
|
||||||
|
dialogsEmptySkip: 2px;
|
||||||
|
dialogsEmptyLabel: FlatLabel(defaultFlatLabel) {
|
||||||
|
minWidth: 32px;
|
||||||
|
align: align(top);
|
||||||
|
textFg: windowSubTextFg;
|
||||||
|
}
|
||||||
|
|
||||||
dialogsMenuToggle: IconButton {
|
dialogsMenuToggle: IconButton {
|
||||||
width: 40px;
|
width: 40px;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
|
|
|
@ -17,6 +17,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "core/shortcuts.h"
|
#include "core/shortcuts.h"
|
||||||
#include "ui/widgets/buttons.h"
|
#include "ui/widgets/buttons.h"
|
||||||
#include "ui/widgets/popup_menu.h"
|
#include "ui/widgets/popup_menu.h"
|
||||||
|
#include "ui/text/text_utilities.h"
|
||||||
#include "ui/text_options.h"
|
#include "ui/text_options.h"
|
||||||
#include "ui/ui_utility.h"
|
#include "ui/ui_utility.h"
|
||||||
#include "data/data_drafts.h"
|
#include "data/data_drafts.h"
|
||||||
|
@ -115,8 +116,6 @@ InnerWidget::InnerWidget(
|
||||||
, _pinnedShiftAnimation([=](crl::time now) {
|
, _pinnedShiftAnimation([=](crl::time now) {
|
||||||
return pinnedShiftAnimationCallback(now);
|
return pinnedShiftAnimationCallback(now);
|
||||||
})
|
})
|
||||||
, _addContactLnk(this, tr::lng_add_contact_button(tr::now))
|
|
||||||
, _editFilterLnk(this, tr::lng_filters_context_edit(tr::now))
|
|
||||||
, _cancelSearchInChat(this, st::dialogsCancelSearchInPeer)
|
, _cancelSearchInChat(this, st::dialogsCancelSearchInPeer)
|
||||||
, _cancelSearchFromUser(this, st::dialogsCancelSearchInPeer) {
|
, _cancelSearchFromUser(this, st::dialogsCancelSearchInPeer) {
|
||||||
|
|
||||||
|
@ -124,8 +123,6 @@ InnerWidget::InnerWidget(
|
||||||
setAttribute(Qt::WA_OpaquePaintEvent, true);
|
setAttribute(Qt::WA_OpaquePaintEvent, true);
|
||||||
#endif // OS_MAC_OLD
|
#endif // OS_MAC_OLD
|
||||||
|
|
||||||
_addContactLnk->addClickHandler([] { App::wnd()->onShowAddContact(); });
|
|
||||||
_editFilterLnk->addClickHandler([=] { editOpenedFilter(); });
|
|
||||||
_cancelSearchInChat->setClickedCallback([=] { cancelSearchInChat(); });
|
_cancelSearchInChat->setClickedCallback([=] { cancelSearchInChat(); });
|
||||||
_cancelSearchInChat->hide();
|
_cancelSearchInChat->hide();
|
||||||
_cancelSearchFromUser->setClickedCallback([=] {
|
_cancelSearchFromUser->setClickedCallback([=] {
|
||||||
|
@ -146,6 +143,7 @@ InnerWidget::InnerWidget(
|
||||||
session().data().contactsLoaded().changes(
|
session().data().contactsLoaded().changes(
|
||||||
) | rpl::start_with_next([=] {
|
) | rpl::start_with_next([=] {
|
||||||
refresh();
|
refresh();
|
||||||
|
refreshEmptyLabel();
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
|
|
||||||
session().data().itemRemoved(
|
session().data().itemRemoved(
|
||||||
|
@ -188,7 +186,9 @@ InnerWidget::InnerWidget(
|
||||||
|
|
||||||
setupOnlineStatusCheck();
|
setupOnlineStatusCheck();
|
||||||
|
|
||||||
session().data().chatsListChanges(
|
rpl::merge(
|
||||||
|
session().data().chatsListChanges(),
|
||||||
|
session().data().chatsListLoadedEvents()
|
||||||
) | rpl::filter([=](Data::Folder *folder) {
|
) | rpl::filter([=](Data::Folder *folder) {
|
||||||
return (folder == _openedFolder);
|
return (folder == _openedFolder);
|
||||||
}) | rpl::start_with_next([=] {
|
}) | rpl::start_with_next([=] {
|
||||||
|
@ -498,19 +498,6 @@ void InnerWidget::paintEvent(QPaintEvent *e) {
|
||||||
}
|
}
|
||||||
if (!otherStart) {
|
if (!otherStart) {
|
||||||
p.fillRect(dialogsClip, st::dialogsBg);
|
p.fillRect(dialogsClip, st::dialogsBg);
|
||||||
p.setFont(st::noContactsFont);
|
|
||||||
p.setPen(st::noContactsColor);
|
|
||||||
const auto phrase = _filterId
|
|
||||||
? (session().data().chatsList()->loaded()
|
|
||||||
? tr::lng_no_chats_filter(tr::now)
|
|
||||||
: tr::lng_contacts_loading(tr::now))
|
|
||||||
: session().data().contactsLoaded().current()
|
|
||||||
? tr::lng_no_chats(tr::now)
|
|
||||||
: tr::lng_contacts_loading(tr::now);
|
|
||||||
p.drawText(
|
|
||||||
QRect(0, 0, fullWidth, st::noContactsHeight - (session().data().contactsLoaded().current() ? st::noContactsFont->height : 0)),
|
|
||||||
phrase,
|
|
||||||
style::al_center);
|
|
||||||
}
|
}
|
||||||
} else if (_state == WidgetState::Filtered) {
|
} else if (_state == WidgetState::Filtered) {
|
||||||
if (!_hashtagResults.empty()) {
|
if (!_hashtagResults.empty()) {
|
||||||
|
@ -1410,8 +1397,7 @@ void InnerWidget::setSearchedPressed(int pressed) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void InnerWidget::resizeEvent(QResizeEvent *e) {
|
void InnerWidget::resizeEvent(QResizeEvent *e) {
|
||||||
_addContactLnk->move((width() - _addContactLnk->width()) / 2, (st::noContactsHeight + st::noContactsFont->height) / 2);
|
resizeEmptyLabel();
|
||||||
_editFilterLnk->move((width() - _editFilterLnk->width()) / 2, (st::noContactsHeight + st::noContactsFont->height) / 2);
|
|
||||||
const auto widthForCancelButton = qMax(width(), st::columnMinimalWidthLeft);
|
const auto widthForCancelButton = qMax(width(), st::columnMinimalWidthLeft);
|
||||||
const auto left = widthForCancelButton - st::dialogsSearchInSkip - _cancelSearchInChat->width();
|
const auto left = widthForCancelButton - st::dialogsSearchInSkip - _cancelSearchInChat->width();
|
||||||
const auto top = (st::dialogsSearchInHeight - st::dialogsCancelSearchInPeer.height) / 2;
|
const auto top = (st::dialogsSearchInHeight - st::dialogsCancelSearchInPeer.height) / 2;
|
||||||
|
@ -2200,19 +2186,12 @@ void InnerWidget::refresh(bool toTop) {
|
||||||
if (needCollapsedRowsRefresh()) {
|
if (needCollapsedRowsRefresh()) {
|
||||||
return refreshWithCollapsedRows(toTop);
|
return refreshWithCollapsedRows(toTop);
|
||||||
}
|
}
|
||||||
|
refreshEmptyLabel();
|
||||||
const auto list = shownDialogs();
|
const auto list = shownDialogs();
|
||||||
_addContactLnk->setVisible(!_filterId
|
|
||||||
&& (_state == WidgetState::Default)
|
|
||||||
&& list->empty()
|
|
||||||
&& session().data().contactsLoaded().current());
|
|
||||||
_editFilterLnk->setVisible((_filterId > 0)
|
|
||||||
&& (_state == WidgetState::Default)
|
|
||||||
&& list->empty()
|
|
||||||
&& session().data().chatsList()->loaded());
|
|
||||||
auto h = 0;
|
auto h = 0;
|
||||||
if (_state == WidgetState::Default) {
|
if (_state == WidgetState::Default) {
|
||||||
if (list->empty()) {
|
if (list->empty()) {
|
||||||
h = st::noContactsHeight;
|
h = st::dialogsEmptyHeight;
|
||||||
} else {
|
} else {
|
||||||
h = dialogsOffset() + list->size() * st::dialogsRowHeight;
|
h = dialogsOffset() + list->size() * st::dialogsRowHeight;
|
||||||
}
|
}
|
||||||
|
@ -2235,6 +2214,69 @@ void InnerWidget::refresh(bool toTop) {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InnerWidget::refreshEmptyLabel() {
|
||||||
|
const auto data = &session().data();
|
||||||
|
const auto state = !shownDialogs()->empty()
|
||||||
|
? EmptyState::None
|
||||||
|
: (!_filterId && data->contactsLoaded().current())
|
||||||
|
? EmptyState::NoContacts
|
||||||
|
: (_filterId > 0) && data->chatsList()->loaded()
|
||||||
|
? EmptyState::EmptyFolder
|
||||||
|
: EmptyState::Loading;
|
||||||
|
if (state == EmptyState::None) {
|
||||||
|
_emptyState = state;
|
||||||
|
_empty.destroy();
|
||||||
|
return;
|
||||||
|
} else if (_emptyState == state) {
|
||||||
|
_empty->setVisible(_state == WidgetState::Default);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_emptyState = state;
|
||||||
|
auto phrase = (state == EmptyState::NoContacts)
|
||||||
|
? tr::lng_no_chats()
|
||||||
|
: (state == EmptyState::EmptyFolder)
|
||||||
|
? tr::lng_no_chats_filter()
|
||||||
|
: tr::lng_contacts_loading();
|
||||||
|
auto link = (state == EmptyState::NoContacts)
|
||||||
|
? tr::lng_add_contact_button()
|
||||||
|
: (state == EmptyState::EmptyFolder)
|
||||||
|
? tr::lng_filters_context_edit()
|
||||||
|
: rpl::single(QString());
|
||||||
|
auto full = rpl::combine(
|
||||||
|
std::move(phrase),
|
||||||
|
std::move(link)
|
||||||
|
) | rpl::map([](const QString &phrase, const QString &link) {
|
||||||
|
auto result = Ui::Text::WithEntities(phrase);
|
||||||
|
if (!link.isEmpty()) {
|
||||||
|
result.append("\n\n").append(Ui::Text::Link(link));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
_empty.create(this, std::move(full), st::dialogsEmptyLabel);
|
||||||
|
resizeEmptyLabel();
|
||||||
|
_empty->setClickHandlerFilter([=](const auto &...) {
|
||||||
|
if (_emptyState == EmptyState::NoContacts) {
|
||||||
|
App::wnd()->onShowAddContact();
|
||||||
|
} else if (_emptyState == EmptyState::EmptyFolder) {
|
||||||
|
editOpenedFilter();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
_empty->setVisible(_state == WidgetState::Default);
|
||||||
|
}
|
||||||
|
|
||||||
|
void InnerWidget::resizeEmptyLabel() {
|
||||||
|
if (!_empty) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto useWidth = std::min(
|
||||||
|
_empty->naturalWidth(),
|
||||||
|
width() - 2 * st::dialogsEmptySkip);
|
||||||
|
const auto left = (width() - useWidth) / 2;
|
||||||
|
_empty->resizeToWidth(useWidth);
|
||||||
|
_empty->move(left, (st::dialogsEmptyHeight - _empty->height()) / 2);
|
||||||
|
}
|
||||||
|
|
||||||
void InnerWidget::clearMouseSelection(bool clearSelection) {
|
void InnerWidget::clearMouseSelection(bool clearSelection) {
|
||||||
_mouseSelection = false;
|
_mouseSelection = false;
|
||||||
_lastMousePosition = std::nullopt;
|
_lastMousePosition = std::nullopt;
|
||||||
|
@ -2580,6 +2622,7 @@ void InnerWidget::switchToFilter(FilterId filterId) {
|
||||||
_filterId = filterId;
|
_filterId = filterId;
|
||||||
refreshWithCollapsedRows(true);
|
refreshWithCollapsedRows(true);
|
||||||
}
|
}
|
||||||
|
refreshEmptyLabel();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool InnerWidget::chooseHashtag() {
|
bool InnerWidget::chooseHashtag() {
|
||||||
|
|
|
@ -22,7 +22,7 @@ class Session;
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class IconButton;
|
class IconButton;
|
||||||
class PopupMenu;
|
class PopupMenu;
|
||||||
class LinkButton;
|
class FlatLabel;
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
|
||||||
namespace Window {
|
namespace Window {
|
||||||
|
@ -97,6 +97,8 @@ public:
|
||||||
|
|
||||||
void clearFilter();
|
void clearFilter();
|
||||||
void refresh(bool toTop = false);
|
void refresh(bool toTop = false);
|
||||||
|
void refreshEmptyLabel();
|
||||||
|
void resizeEmptyLabel();
|
||||||
|
|
||||||
bool chooseRow();
|
bool chooseRow();
|
||||||
|
|
||||||
|
@ -168,6 +170,13 @@ private:
|
||||||
NextOrOriginal,
|
NextOrOriginal,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class EmptyState : uchar {
|
||||||
|
None,
|
||||||
|
Loading,
|
||||||
|
NoContacts,
|
||||||
|
EmptyFolder,
|
||||||
|
};
|
||||||
|
|
||||||
Main::Session &session() const;
|
Main::Session &session() const;
|
||||||
|
|
||||||
void dialogRowReplaced(Row *oldRow, Row *newRow);
|
void dialogRowReplaced(Row *oldRow, Row *newRow);
|
||||||
|
@ -357,6 +366,7 @@ private:
|
||||||
int _filteredPressed = -1;
|
int _filteredPressed = -1;
|
||||||
|
|
||||||
bool _waitingForSearch = false;
|
bool _waitingForSearch = false;
|
||||||
|
EmptyState _emptyState = EmptyState::None;
|
||||||
|
|
||||||
QString _peerSearchQuery;
|
QString _peerSearchQuery;
|
||||||
std::vector<std::unique_ptr<PeerSearchResult>> _peerSearchResults;
|
std::vector<std::unique_ptr<PeerSearchResult>> _peerSearchResults;
|
||||||
|
@ -376,8 +386,7 @@ private:
|
||||||
|
|
||||||
WidgetState _state = WidgetState::Default;
|
WidgetState _state = WidgetState::Default;
|
||||||
|
|
||||||
object_ptr<Ui::LinkButton> _addContactLnk;
|
object_ptr<Ui::FlatLabel> _empty = { nullptr };
|
||||||
object_ptr<Ui::LinkButton> _editFilterLnk;
|
|
||||||
object_ptr<Ui::IconButton> _cancelSearchInChat;
|
object_ptr<Ui::IconButton> _cancelSearchInChat;
|
||||||
object_ptr<Ui::IconButton> _cancelSearchFromUser;
|
object_ptr<Ui::IconButton> _cancelSearchFromUser;
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 86cb882aab071c2a7933fcfc8d0834e38dca3651
|
Subproject commit 14c5da49f9e9c8a3495fb2f270ce94e7b9073ef5
|
Loading…
Reference in New Issue