mirror of https://github.com/procxx/kepka.git
Allow collapsing archive in the chats list.
This commit is contained in:
parent
6f885fb6cc
commit
4356b1c193
|
@ -1285,6 +1285,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_context_unpin_from_top" = "Unpin from top";
|
"lng_context_unpin_from_top" = "Unpin from top";
|
||||||
"lng_context_mark_unread" = "Mark as unread";
|
"lng_context_mark_unread" = "Mark as unread";
|
||||||
"lng_context_mark_read" = "Mark as read";
|
"lng_context_mark_read" = "Mark as read";
|
||||||
|
"lng_context_archive_expand" = "Expand";
|
||||||
|
"lng_context_archive_collapse" = "Collapse";
|
||||||
|
|
||||||
"lng_context_promote_admin" = "Promote to admin";
|
"lng_context_promote_admin" = "Promote to admin";
|
||||||
"lng_context_edit_permissions" = "Edit permissions";
|
"lng_context_edit_permissions" = "Edit permissions";
|
||||||
|
|
|
@ -93,6 +93,7 @@ QByteArray AuthSessionSettings::serialize() const {
|
||||||
stream << qint32(_variables.exeLaunchWarning ? 1 : 0);
|
stream << qint32(_variables.exeLaunchWarning ? 1 : 0);
|
||||||
stream << autoDownload;
|
stream << autoDownload;
|
||||||
stream << qint32(_variables.supportAllSearchResults.current() ? 1 : 0);
|
stream << qint32(_variables.supportAllSearchResults.current() ? 1 : 0);
|
||||||
|
stream << qint32(_variables.archiveCollapsed.current() ? 1 : 0);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -129,6 +130,7 @@ void AuthSessionSettings::constructFromSerialized(const QByteArray &serialized)
|
||||||
qint32 exeLaunchWarning = _variables.exeLaunchWarning ? 1 : 0;
|
qint32 exeLaunchWarning = _variables.exeLaunchWarning ? 1 : 0;
|
||||||
QByteArray autoDownload;
|
QByteArray autoDownload;
|
||||||
qint32 supportAllSearchResults = _variables.supportAllSearchResults.current() ? 1 : 0;
|
qint32 supportAllSearchResults = _variables.supportAllSearchResults.current() ? 1 : 0;
|
||||||
|
qint32 archiveCollapsed = _variables.archiveCollapsed.current() ? 1 : 0;
|
||||||
|
|
||||||
stream >> selectorTab;
|
stream >> selectorTab;
|
||||||
stream >> lastSeenWarningSeen;
|
stream >> lastSeenWarningSeen;
|
||||||
|
@ -208,6 +210,9 @@ void AuthSessionSettings::constructFromSerialized(const QByteArray &serialized)
|
||||||
if (!stream.atEnd()) {
|
if (!stream.atEnd()) {
|
||||||
stream >> supportAllSearchResults;
|
stream >> supportAllSearchResults;
|
||||||
}
|
}
|
||||||
|
if (!stream.atEnd()) {
|
||||||
|
stream >> archiveCollapsed;
|
||||||
|
}
|
||||||
if (stream.status() != QDataStream::Ok) {
|
if (stream.status() != QDataStream::Ok) {
|
||||||
LOG(("App Error: "
|
LOG(("App Error: "
|
||||||
"Bad data for AuthSessionSettings::constructFromSerialized()"));
|
"Bad data for AuthSessionSettings::constructFromSerialized()"));
|
||||||
|
@ -277,6 +282,7 @@ void AuthSessionSettings::constructFromSerialized(const QByteArray &serialized)
|
||||||
_variables.countUnreadMessages = (countUnreadMessages == 1);
|
_variables.countUnreadMessages = (countUnreadMessages == 1);
|
||||||
_variables.exeLaunchWarning = (exeLaunchWarning == 1);
|
_variables.exeLaunchWarning = (exeLaunchWarning == 1);
|
||||||
_variables.supportAllSearchResults = (supportAllSearchResults == 1);
|
_variables.supportAllSearchResults = (supportAllSearchResults == 1);
|
||||||
|
_variables.archiveCollapsed = (archiveCollapsed == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AuthSessionSettings::setSupportChatsTimeSlice(int slice) {
|
void AuthSessionSettings::setSupportChatsTimeSlice(int slice) {
|
||||||
|
@ -371,8 +377,20 @@ rpl::producer<int> AuthSessionSettings::thirdColumnWidthChanges() const {
|
||||||
return _variables.thirdColumnWidth.changes();
|
return _variables.thirdColumnWidth.changes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AuthSessionSettings::setArchiveCollapsed(bool collapsed) {
|
||||||
|
_variables.archiveCollapsed = collapsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AuthSessionSettings::archiveCollapsed() const {
|
||||||
|
return _variables.archiveCollapsed.current();
|
||||||
|
}
|
||||||
|
|
||||||
|
rpl::producer<bool> AuthSessionSettings::archiveCollapsedChanges() const {
|
||||||
|
return _variables.archiveCollapsed.changes();
|
||||||
|
}
|
||||||
|
|
||||||
AuthSession &Auth() {
|
AuthSession &Auth() {
|
||||||
auto result = Core::App().authSession();
|
const auto result = Core::App().authSession();
|
||||||
Assert(result != nullptr);
|
Assert(result != nullptr);
|
||||||
return *result;
|
return *result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -188,6 +188,10 @@ public:
|
||||||
return _variables.autoDownload;
|
return _variables.autoDownload;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setArchiveCollapsed(bool collapsed);
|
||||||
|
bool archiveCollapsed() const;
|
||||||
|
rpl::producer<bool> archiveCollapsedChanges() const;
|
||||||
|
|
||||||
bool hadLegacyCallsPeerToPeerNobody() const {
|
bool hadLegacyCallsPeerToPeerNobody() const {
|
||||||
return _variables.hadLegacyCallsPeerToPeerNobody;
|
return _variables.hadLegacyCallsPeerToPeerNobody;
|
||||||
}
|
}
|
||||||
|
@ -240,6 +244,7 @@ private:
|
||||||
bool countUnreadMessages = true;
|
bool countUnreadMessages = true;
|
||||||
bool exeLaunchWarning = true;
|
bool exeLaunchWarning = true;
|
||||||
Data::AutoDownload::Full autoDownload;
|
Data::AutoDownload::Full autoDownload;
|
||||||
|
rpl::variable<bool> archiveCollapsed = false;
|
||||||
|
|
||||||
static constexpr auto kDefaultSupportChatsLimitSlice
|
static constexpr auto kDefaultSupportChatsLimitSlice
|
||||||
= 7 * 24 * 60 * 60;
|
= 7 * 24 * 60 * 60;
|
||||||
|
|
|
@ -75,29 +75,30 @@ FolderId Folder::id() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Folder::indexNameParts() {
|
void Folder::indexNameParts() {
|
||||||
_nameWords.clear();
|
// We don't want archive to be filtered in the chats list.
|
||||||
_nameFirstLetters.clear();
|
//_nameWords.clear();
|
||||||
auto toIndexList = QStringList();
|
//_nameFirstLetters.clear();
|
||||||
auto appendToIndex = [&](const QString &value) {
|
//auto toIndexList = QStringList();
|
||||||
if (!value.isEmpty()) {
|
//auto appendToIndex = [&](const QString &value) {
|
||||||
toIndexList.push_back(TextUtilities::RemoveAccents(value));
|
// if (!value.isEmpty()) {
|
||||||
}
|
// toIndexList.push_back(TextUtilities::RemoveAccents(value));
|
||||||
};
|
// }
|
||||||
|
//};
|
||||||
|
|
||||||
appendToIndex(_name);
|
//appendToIndex(_name);
|
||||||
const auto appendTranslit = !toIndexList.isEmpty()
|
//const auto appendTranslit = !toIndexList.isEmpty()
|
||||||
&& cRussianLetters().match(toIndexList.front()).hasMatch();
|
// && cRussianLetters().match(toIndexList.front()).hasMatch();
|
||||||
if (appendTranslit) {
|
//if (appendTranslit) {
|
||||||
appendToIndex(translitRusEng(toIndexList.front()));
|
// appendToIndex(translitRusEng(toIndexList.front()));
|
||||||
}
|
//}
|
||||||
auto toIndex = toIndexList.join(' ');
|
//auto toIndex = toIndexList.join(' ');
|
||||||
toIndex += ' ' + rusKeyboardLayoutSwitch(toIndex);
|
//toIndex += ' ' + rusKeyboardLayoutSwitch(toIndex);
|
||||||
|
|
||||||
const auto namesList = TextUtilities::PrepareSearchWords(toIndex);
|
//const auto namesList = TextUtilities::PrepareSearchWords(toIndex);
|
||||||
for (const auto &name : namesList) {
|
//for (const auto &name : namesList) {
|
||||||
_nameWords.insert(name);
|
// _nameWords.insert(name);
|
||||||
_nameFirstLetters.insert(name[0]);
|
// _nameFirstLetters.insert(name[0]);
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Folder::registerOne(not_null<History*> history) {
|
void Folder::registerOne(not_null<History*> history) {
|
||||||
|
|
|
@ -74,7 +74,11 @@ int PinnedDialogsCount(not_null<Dialogs::IndexedList*> list) {
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
struct InnerWidget::ImportantSwitch {
|
struct InnerWidget::CollapsedRow {
|
||||||
|
explicit CollapsedRow(Data::Folder *folder = nullptr) : folder(folder) {
|
||||||
|
}
|
||||||
|
|
||||||
|
Data::Folder *folder = nullptr;
|
||||||
RippleRow row;
|
RippleRow row;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -108,10 +112,10 @@ InnerWidget::InnerWidget(
|
||||||
setAttribute(Qt::WA_OpaquePaintEvent, true);
|
setAttribute(Qt::WA_OpaquePaintEvent, true);
|
||||||
#endif // OS_MAC_OLD
|
#endif // OS_MAC_OLD
|
||||||
|
|
||||||
if (Global::DialogsModeEnabled()) {
|
_mode = Global::DialogsModeEnabled()
|
||||||
_importantSwitch = std::make_unique<ImportantSwitch>();
|
? Global::DialogsMode()
|
||||||
_mode = Global::DialogsMode();
|
: Dialogs::Mode::All;
|
||||||
}
|
|
||||||
connect(_addContactLnk, SIGNAL(clicked()), App::wnd(), SLOT(onShowAddContact()));
|
connect(_addContactLnk, SIGNAL(clicked()), App::wnd(), SLOT(onShowAddContact()));
|
||||||
_cancelSearchInChat->setClickedCallback([=] { cancelSearchInChat(); });
|
_cancelSearchInChat->setClickedCallback([=] { cancelSearchInChat(); });
|
||||||
_cancelSearchInChat->hide();
|
_cancelSearchInChat->hide();
|
||||||
|
@ -180,6 +184,11 @@ InnerWidget::InnerWidget(
|
||||||
refresh();
|
refresh();
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
|
|
||||||
|
session().settings().archiveCollapsedChanges(
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
refreshWithCollapsedRows();
|
||||||
|
}, lifetime());
|
||||||
|
|
||||||
subscribe(Window::Theme::Background(), [=](const Window::Theme::BackgroundUpdate &data) {
|
subscribe(Window::Theme::Background(), [=](const Window::Theme::BackgroundUpdate &data) {
|
||||||
if (data.paletteChanged()) {
|
if (data.paletteChanged()) {
|
||||||
Layout::clearUnreadBadgesCache();
|
Layout::clearUnreadBadgesCache();
|
||||||
|
@ -225,7 +234,8 @@ InnerWidget::InnerWidget(
|
||||||
updateDialogRow(previous);
|
updateDialogRow(previous);
|
||||||
updateDialogRow(next);
|
updateDialogRow(next);
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
refresh();
|
|
||||||
|
refreshWithCollapsedRows(true);
|
||||||
|
|
||||||
setupShortcuts();
|
setupShortcuts();
|
||||||
}
|
}
|
||||||
|
@ -249,17 +259,50 @@ void InnerWidget::handleChatMigration(not_null<ChatData*> chat) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool InnerWidget::importantSwitchShown() const {
|
void InnerWidget::refreshWithCollapsedRows(bool toTop) {
|
||||||
return !_openedFolder && _importantSwitch;
|
const auto pressed = _collapsedPressed;
|
||||||
|
const auto selected = _collapsedSelected;
|
||||||
|
|
||||||
|
setCollapsedPressed(-1);
|
||||||
|
_collapsedSelected = -1;
|
||||||
|
|
||||||
|
_collapsedRows.clear();
|
||||||
|
if (!_openedFolder && Global::DialogsModeEnabled()) {
|
||||||
|
_collapsedRows.push_back(std::make_unique<CollapsedRow>());
|
||||||
|
}
|
||||||
|
const auto list = shownDialogs();
|
||||||
|
const auto archive = !list->empty()
|
||||||
|
? (*list->begin())->folder()
|
||||||
|
: nullptr;
|
||||||
|
if (archive && session().settings().archiveCollapsed()) {
|
||||||
|
if (_selected && _selected->folder() == archive) {
|
||||||
|
_selected = nullptr;
|
||||||
|
}
|
||||||
|
if (_pressed && _pressed->folder() == archive) {
|
||||||
|
setPressed(nullptr);
|
||||||
|
}
|
||||||
|
_skipByCollapsedRows = 1;
|
||||||
|
_collapsedRows.push_back(std::make_unique<CollapsedRow>(archive));
|
||||||
|
} else {
|
||||||
|
_skipByCollapsedRows = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
refresh(toTop);
|
||||||
|
|
||||||
|
if (selected >= 0 && selected < _collapsedRows.size()) {
|
||||||
|
_collapsedSelected = selected;
|
||||||
|
}
|
||||||
|
if (pressed >= 0 && pressed < _collapsedRows.size()) {
|
||||||
|
setCollapsedPressed(pressed);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int InnerWidget::dialogsOffset() const {
|
int InnerWidget::dialogsOffset() const {
|
||||||
return importantSwitchShown()
|
return _collapsedRows.size() * st::dialogsImportantBarHeight
|
||||||
? st::dialogsImportantBarHeight
|
- _skipByCollapsedRows * st::dialogsRowHeight;
|
||||||
: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int InnerWidget::proxyPromotedCount() const {
|
int InnerWidget::fixedOnTopCount() const {
|
||||||
auto result = 0;
|
auto result = 0;
|
||||||
for (const auto row : *shownDialogs()) {
|
for (const auto row : *shownDialogs()) {
|
||||||
if (row->entry()->fixedOnTopIndex()) {
|
if (row->entry()->fixedOnTopIndex()) {
|
||||||
|
@ -272,7 +315,7 @@ int InnerWidget::proxyPromotedCount() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
int InnerWidget::pinnedOffset() const {
|
int InnerWidget::pinnedOffset() const {
|
||||||
return dialogsOffset() + proxyPromotedCount() * st::dialogsRowHeight;
|
return dialogsOffset() + fixedOnTopCount() * st::dialogsRowHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
int InnerWidget::filteredOffset() const {
|
int InnerWidget::filteredOffset() const {
|
||||||
|
@ -309,7 +352,7 @@ void InnerWidget::changeOpenedFolder(Data::Folder *folder) {
|
||||||
clearSelection();
|
clearSelection();
|
||||||
_openedFolder = folder;
|
_openedFolder = folder;
|
||||||
_mode = _openedFolder ? Mode::All : Global::DialogsMode();
|
_mode = _openedFolder ? Mode::All : Global::DialogsMode();
|
||||||
refresh(true);
|
refreshWithCollapsedRows(true);
|
||||||
// This doesn't work, because we clear selection in leaveEvent on hide.
|
// This doesn't work, because we clear selection in leaveEvent on hide.
|
||||||
//if (mouseSelection && lastMousePosition) {
|
//if (mouseSelection && lastMousePosition) {
|
||||||
// selectByMouse(*lastMousePosition);
|
// selectByMouse(*lastMousePosition);
|
||||||
|
@ -331,14 +374,11 @@ void InnerWidget::paintEvent(QPaintEvent *e) {
|
||||||
auto dialogsClip = r;
|
auto dialogsClip = r;
|
||||||
auto ms = crl::now();
|
auto ms = crl::now();
|
||||||
if (_state == WidgetState::Default) {
|
if (_state == WidgetState::Default) {
|
||||||
auto rows = shownDialogs();
|
paintCollapsedRows(p, r);
|
||||||
if (importantSwitchShown()) {
|
|
||||||
auto selected = isPressed() ? _importantSwitchPressed : _importantSwitchSelected;
|
const auto rows = shownDialogs();
|
||||||
Layout::paintImportantSwitch(p, _mode, fullWidth, selected);
|
const auto &list = rows->all();
|
||||||
dialogsClip.translate(0, -st::dialogsImportantBarHeight);
|
const auto otherStart = std::max(int(rows->size()) - _skipByCollapsedRows, 0) * st::dialogsRowHeight;
|
||||||
p.translate(0, st::dialogsImportantBarHeight);
|
|
||||||
}
|
|
||||||
auto otherStart = rows->size() * st::dialogsRowHeight;
|
|
||||||
const auto active = activeEntry.key;
|
const auto active = activeEntry.key;
|
||||||
const auto selected = _menuRow.key
|
const auto selected = _menuRow.key
|
||||||
? _menuRow.key
|
? _menuRow.key
|
||||||
|
@ -350,13 +390,13 @@ void InnerWidget::paintEvent(QPaintEvent *e) {
|
||||||
? _selected->key()
|
? _selected->key()
|
||||||
: Key()));
|
: Key()));
|
||||||
if (otherStart) {
|
if (otherStart) {
|
||||||
|
const auto skip = dialogsOffset();
|
||||||
auto reorderingPinned = (_aboveIndex >= 0 && !_pinnedRows.empty());
|
auto reorderingPinned = (_aboveIndex >= 0 && !_pinnedRows.empty());
|
||||||
auto &list = rows->all();
|
|
||||||
if (reorderingPinned) {
|
if (reorderingPinned) {
|
||||||
dialogsClip = dialogsClip.marginsAdded(QMargins(0, st::dialogsRowHeight, 0, st::dialogsRowHeight));
|
dialogsClip = dialogsClip.marginsAdded(QMargins(0, st::dialogsRowHeight, 0, st::dialogsRowHeight));
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto promoted = proxyPromotedCount();
|
const auto promoted = fixedOnTopCount();
|
||||||
const auto paintDialog = [&](not_null<Row*> row) {
|
const auto paintDialog = [&](not_null<Row*> row) {
|
||||||
const auto pinned = row->pos() - promoted;
|
const auto pinned = row->pos() - promoted;
|
||||||
const auto count = _pinnedRows.size();
|
const auto count = _pinnedRows.size();
|
||||||
|
@ -381,19 +421,22 @@ void InnerWidget::paintEvent(QPaintEvent *e) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
auto i = list.cfind(dialogsClip.top(), st::dialogsRowHeight);
|
auto i = list.cfind(dialogsClip.top() - skip, st::dialogsRowHeight);
|
||||||
|
while (i != list.cend() && (*i)->pos() < _skipByCollapsedRows) {
|
||||||
|
++i;
|
||||||
|
}
|
||||||
if (i != list.cend()) {
|
if (i != list.cend()) {
|
||||||
auto lastPaintedPos = (*i)->pos();
|
auto lastPaintedPos = (*i)->pos();
|
||||||
|
|
||||||
// If we're reordering pinned chats we need to fill this area background first.
|
// If we're reordering pinned chats we need to fill this area background first.
|
||||||
if (reorderingPinned) {
|
if (reorderingPinned) {
|
||||||
p.fillRect(0, promoted * st::dialogsRowHeight, fullWidth, st::dialogsRowHeight * _pinnedRows.size(), st::dialogsBg);
|
p.fillRect(0, (promoted - _skipByCollapsedRows) * st::dialogsRowHeight, fullWidth, st::dialogsRowHeight * _pinnedRows.size(), st::dialogsBg);
|
||||||
}
|
}
|
||||||
|
|
||||||
p.translate(0, lastPaintedPos * st::dialogsRowHeight);
|
p.translate(0, (lastPaintedPos - _skipByCollapsedRows) * st::dialogsRowHeight);
|
||||||
for (auto e = list.cend(); i != e; ++i) {
|
for (auto e = list.cend(); i != e; ++i) {
|
||||||
auto row = (*i);
|
auto row = (*i);
|
||||||
if (lastPaintedPos * st::dialogsRowHeight >= dialogsClip.top() + dialogsClip.height()) {
|
if ((lastPaintedPos - _skipByCollapsedRows) * st::dialogsRowHeight >= dialogsClip.top() - skip + dialogsClip.height()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -591,6 +634,42 @@ void InnerWidget::paintEvent(QPaintEvent *e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InnerWidget::paintCollapsedRows(Painter &p, QRect clip) const {
|
||||||
|
auto index = 0;
|
||||||
|
const auto rowHeight = st::dialogsImportantBarHeight;
|
||||||
|
for (const auto &row : _collapsedRows) {
|
||||||
|
const auto increment = gsl::finally([&] {
|
||||||
|
p.translate(0, rowHeight);
|
||||||
|
++index;
|
||||||
|
});
|
||||||
|
|
||||||
|
const auto y = index * rowHeight;
|
||||||
|
if (!clip.intersects(QRect(0, y, width(), rowHeight))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const auto selected = (index == _collapsedSelected)
|
||||||
|
|| (index == _collapsedPressed);
|
||||||
|
paintCollapsedRow(p, row.get(), selected);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void InnerWidget::paintCollapsedRow(
|
||||||
|
Painter &p,
|
||||||
|
not_null<const CollapsedRow*> row,
|
||||||
|
bool selected) const {
|
||||||
|
const auto text = row->folder
|
||||||
|
? row->folder->chatListName()
|
||||||
|
: (_mode == Dialogs::Mode::Important)
|
||||||
|
? lang(lng_dialogs_show_all_chats)
|
||||||
|
: lang(lng_dialogs_hide_muted_chats);
|
||||||
|
const auto unread = row->folder
|
||||||
|
? row->folder->chatListUnreadCount()
|
||||||
|
: (_mode == Dialogs::Mode::Important)
|
||||||
|
? session().data().unreadOnlyMutedBadge()
|
||||||
|
: 0;
|
||||||
|
Layout::PaintCollapsedRow(p, row->row, text, unread, width(), selected);
|
||||||
|
}
|
||||||
|
|
||||||
bool InnerWidget::isSearchResultActive(
|
bool InnerWidget::isSearchResultActive(
|
||||||
not_null<FakeRow*> result,
|
not_null<FakeRow*> result,
|
||||||
const RowDescriptor &entry) const {
|
const RowDescriptor &entry) const {
|
||||||
|
@ -791,8 +870,8 @@ void InnerWidget::clearIrrelevantState() {
|
||||||
_searchedSelected = -1;
|
_searchedSelected = -1;
|
||||||
setSearchedPressed(-1);
|
setSearchedPressed(-1);
|
||||||
} else if (_state == WidgetState::Filtered) {
|
} else if (_state == WidgetState::Filtered) {
|
||||||
_importantSwitchSelected = false;
|
_collapsedSelected = -1;
|
||||||
setImportantSwitchPressed(false);
|
setCollapsedPressed(-1);
|
||||||
_selected = nullptr;
|
_selected = nullptr;
|
||||||
setPressed(nullptr);
|
setPressed(nullptr);
|
||||||
}
|
}
|
||||||
|
@ -810,22 +889,26 @@ void InnerWidget::selectByMouse(QPoint globalPosition) {
|
||||||
const auto mouseY = local.y();
|
const auto mouseY = local.y();
|
||||||
clearIrrelevantState();
|
clearIrrelevantState();
|
||||||
if (_state == WidgetState::Default) {
|
if (_state == WidgetState::Default) {
|
||||||
const auto switchTop = 0;
|
const auto offset = dialogsOffset();
|
||||||
const auto switchBottom = dialogsOffset();
|
const auto collapsedSelected = (mouseY >= 0
|
||||||
const auto importantSwitchSelected = importantSwitchShown()
|
&& mouseY < _collapsedRows.size() * st::dialogsImportantBarHeight)
|
||||||
&& (mouseY >= switchTop)
|
? (mouseY / st::dialogsImportantBarHeight)
|
||||||
&& (mouseY < switchBottom);
|
: -1;
|
||||||
const auto selected = importantSwitchSelected
|
const auto selected = (collapsedSelected >= 0)
|
||||||
? nullptr
|
? nullptr
|
||||||
: (mouseY >= switchBottom)
|
: (mouseY >= offset)
|
||||||
? shownDialogs()->rowAtY(mouseY - switchBottom, st::dialogsRowHeight)
|
? shownDialogs()->rowAtY(
|
||||||
|
mouseY - offset,
|
||||||
|
st::dialogsRowHeight)
|
||||||
: nullptr;
|
: nullptr;
|
||||||
if (_selected != selected || _importantSwitchSelected != importantSwitchSelected) {
|
if (_selected != selected || _collapsedSelected != collapsedSelected) {
|
||||||
updateSelectedRow();
|
updateSelectedRow();
|
||||||
_selected = selected;
|
_selected = selected;
|
||||||
_importantSwitchSelected = importantSwitchSelected;
|
_collapsedSelected = collapsedSelected;
|
||||||
updateSelectedRow();
|
updateSelectedRow();
|
||||||
setCursor((_selected || _importantSwitchSelected) ? style::cur_pointer : style::cur_default);
|
setCursor((_selected || _collapsedSelected)
|
||||||
|
? style::cur_pointer
|
||||||
|
: style::cur_default);
|
||||||
}
|
}
|
||||||
} else if (_state == WidgetState::Filtered) {
|
} else if (_state == WidgetState::Filtered) {
|
||||||
auto wasSelected = isSelected();
|
auto wasSelected = isSelected();
|
||||||
|
@ -892,15 +975,16 @@ void InnerWidget::mousePressEvent(QMouseEvent *e) {
|
||||||
|
|
||||||
_pressButton = e->button();
|
_pressButton = e->button();
|
||||||
setPressed(_selected);
|
setPressed(_selected);
|
||||||
setImportantSwitchPressed(_importantSwitchSelected);
|
setCollapsedPressed(_collapsedSelected);
|
||||||
setHashtagPressed(_hashtagSelected);
|
setHashtagPressed(_hashtagSelected);
|
||||||
_hashtagDeletePressed = _hashtagDeleteSelected;
|
_hashtagDeletePressed = _hashtagDeleteSelected;
|
||||||
setFilteredPressed(_filteredSelected);
|
setFilteredPressed(_filteredSelected);
|
||||||
setPeerSearchPressed(_peerSearchSelected);
|
setPeerSearchPressed(_peerSearchSelected);
|
||||||
setSearchedPressed(_searchedSelected);
|
setSearchedPressed(_searchedSelected);
|
||||||
if (_importantSwitchPressed) {
|
if (base::in_range(_collapsedSelected, 0, _collapsedRows.size())) {
|
||||||
_importantSwitch->row.addRipple(e->pos(), QSize(width(), st::dialogsImportantBarHeight), [this] {
|
auto row = &_collapsedRows[_collapsedSelected]->row;
|
||||||
update(0, 0, width(), st::dialogsImportantBarHeight);
|
row->addRipple(e->pos(), QSize(width(), st::dialogsImportantBarHeight), [this, index = _collapsedSelected] {
|
||||||
|
update(0, (index * st::dialogsImportantBarHeight), width(), st::dialogsImportantBarHeight);
|
||||||
});
|
});
|
||||||
} else if (_pressed) {
|
} else if (_pressed) {
|
||||||
auto row = _pressed;
|
auto row = _pressed;
|
||||||
|
@ -1170,8 +1254,8 @@ void InnerWidget::mousePressReleased(
|
||||||
finishReorderPinned();
|
finishReorderPinned();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto importantSwitchPressed = _importantSwitchPressed;
|
auto collapsedPressed = _collapsedPressed;
|
||||||
setImportantSwitchPressed(false);
|
setCollapsedPressed(-1);
|
||||||
auto pressed = _pressed;
|
auto pressed = _pressed;
|
||||||
setPressed(nullptr);
|
setPressed(nullptr);
|
||||||
auto hashtagPressed = _hashtagPressed;
|
auto hashtagPressed = _hashtagPressed;
|
||||||
|
@ -1189,28 +1273,27 @@ void InnerWidget::mousePressReleased(
|
||||||
}
|
}
|
||||||
updateSelectedRow();
|
updateSelectedRow();
|
||||||
if (!wasDragging && button == Qt::LeftButton) {
|
if (!wasDragging && button == Qt::LeftButton) {
|
||||||
if (importantSwitchPressed && importantSwitchPressed == _importantSwitchSelected) {
|
if ((collapsedPressed >= 0 && collapsedPressed == _collapsedSelected)
|
||||||
chooseRow();
|
|| (pressed && pressed == _selected)
|
||||||
} else if (pressed && pressed == _selected) {
|
|| (hashtagPressed >= 0
|
||||||
chooseRow();
|
&& hashtagPressed == _hashtagSelected
|
||||||
} else if (hashtagPressed >= 0 && hashtagPressed == _hashtagSelected && hashtagDeletePressed == _hashtagDeleteSelected) {
|
&& hashtagDeletePressed == _hashtagDeleteSelected)
|
||||||
chooseRow();
|
|| (filteredPressed >= 0 && filteredPressed == _filteredSelected)
|
||||||
} else if (filteredPressed >= 0 && filteredPressed == _filteredSelected) {
|
|| (peerSearchPressed >= 0
|
||||||
chooseRow();
|
&& peerSearchPressed == _peerSearchSelected)
|
||||||
} else if (peerSearchPressed >= 0 && peerSearchPressed == _peerSearchSelected) {
|
|| (searchedPressed >= 0
|
||||||
chooseRow();
|
&& searchedPressed == _searchedSelected)) {
|
||||||
} else if (searchedPressed >= 0 && searchedPressed == _searchedSelected) {
|
|
||||||
chooseRow();
|
chooseRow();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void InnerWidget::setImportantSwitchPressed(bool pressed) {
|
void InnerWidget::setCollapsedPressed(int pressed) {
|
||||||
if (_importantSwitchPressed != pressed) {
|
if (_collapsedPressed != pressed) {
|
||||||
if (_importantSwitchPressed) {
|
if (_collapsedPressed >= 0) {
|
||||||
_importantSwitch->row.stopLastRipple();
|
_collapsedRows[_collapsedPressed]->row.stopLastRipple();
|
||||||
}
|
}
|
||||||
_importantSwitchPressed = pressed;
|
_collapsedPressed = pressed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1360,11 +1443,23 @@ void InnerWidget::removeDialog(Key key) {
|
||||||
refresh();
|
refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InnerWidget::repaintCollapsedFolderRow(not_null<Data::Folder*> folder) {
|
||||||
|
for (auto i = 0, l = int(_collapsedRows.size()); i != l; ++i) {
|
||||||
|
if (_collapsedRows[i]->folder == folder) {
|
||||||
|
update(0, i * st::dialogsImportantBarHeight, width(), st::dialogsImportantBarHeight);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void InnerWidget::repaintDialogRow(
|
void InnerWidget::repaintDialogRow(
|
||||||
Mode list,
|
Mode list,
|
||||||
not_null<Row*> row) {
|
not_null<Row*> row) {
|
||||||
if (_state == WidgetState::Default) {
|
if (_state == WidgetState::Default) {
|
||||||
if (_mode == list) {
|
if (_mode == list) {
|
||||||
|
if (const auto folder = row->folder()) {
|
||||||
|
repaintCollapsedFolderRow(folder);
|
||||||
|
}
|
||||||
auto position = row->pos();
|
auto position = row->pos();
|
||||||
auto top = dialogsOffset();
|
auto top = dialogsOffset();
|
||||||
if (base::in_range(position, 0, _pinnedRows.size())) {
|
if (base::in_range(position, 0, _pinnedRows.size())) {
|
||||||
|
@ -1435,6 +1530,9 @@ void InnerWidget::updateDialogRow(
|
||||||
};
|
};
|
||||||
if (_state == WidgetState::Default) {
|
if (_state == WidgetState::Default) {
|
||||||
if (sections & UpdateRowSection::Default) {
|
if (sections & UpdateRowSection::Default) {
|
||||||
|
if (const auto folder = row.key.folder()) {
|
||||||
|
repaintCollapsedFolderRow(folder);
|
||||||
|
}
|
||||||
if (const auto dialog = shownDialogs()->getRow(row.key)) {
|
if (const auto dialog = shownDialogs()->getRow(row.key)) {
|
||||||
const auto position = dialog->pos();
|
const auto position = dialog->pos();
|
||||||
auto top = dialogsOffset();
|
auto top = dialogsOffset();
|
||||||
|
@ -1505,8 +1603,8 @@ void InnerWidget::updateSelectedRow(Key key) {
|
||||||
update(0, top + position * st::dialogsRowHeight, width(), st::dialogsRowHeight);
|
update(0, top + position * st::dialogsRowHeight, width(), st::dialogsRowHeight);
|
||||||
} else if (_selected) {
|
} else if (_selected) {
|
||||||
update(0, dialogsOffset() + _selected->pos() * st::dialogsRowHeight, width(), st::dialogsRowHeight);
|
update(0, dialogsOffset() + _selected->pos() * st::dialogsRowHeight, width(), st::dialogsRowHeight);
|
||||||
} else if (_importantSwitchSelected) {
|
} else if (_collapsedSelected >= 0) {
|
||||||
update(0, 0, width(), st::dialogsImportantBarHeight);
|
update(0, _collapsedSelected * st::dialogsImportantBarHeight, width(), st::dialogsImportantBarHeight);
|
||||||
}
|
}
|
||||||
} else if (_state == WidgetState::Filtered) {
|
} else if (_state == WidgetState::Filtered) {
|
||||||
if (key) {
|
if (key) {
|
||||||
|
@ -1545,14 +1643,9 @@ void InnerWidget::dragLeft() {
|
||||||
void InnerWidget::clearSelection() {
|
void InnerWidget::clearSelection() {
|
||||||
_mouseSelection = false;
|
_mouseSelection = false;
|
||||||
_lastMousePosition = std::nullopt;
|
_lastMousePosition = std::nullopt;
|
||||||
if (_importantSwitchSelected
|
if (isSelected()) {
|
||||||
|| _selected
|
|
||||||
|| _filteredSelected >= 0
|
|
||||||
|| _hashtagSelected >= 0
|
|
||||||
|| _peerSearchSelected >= 0
|
|
||||||
|| _searchedSelected >= 0) {
|
|
||||||
updateSelectedRow();
|
updateSelectedRow();
|
||||||
_importantSwitchSelected = false;
|
_collapsedSelected = -1;
|
||||||
_selected = nullptr;
|
_selected = nullptr;
|
||||||
_filteredSelected
|
_filteredSelected
|
||||||
= _searchedSelected
|
= _searchedSelected
|
||||||
|
@ -1583,6 +1676,10 @@ void InnerWidget::contextMenuEvent(QContextMenuEvent *e) {
|
||||||
if (_state == WidgetState::Default) {
|
if (_state == WidgetState::Default) {
|
||||||
if (_selected) {
|
if (_selected) {
|
||||||
return { _selected->key(), FullMsgId() };
|
return { _selected->key(), FullMsgId() };
|
||||||
|
} else if (base::in_range(_collapsedSelected, 0, _collapsedRows.size())) {
|
||||||
|
if (const auto folder = _collapsedRows[_collapsedSelected]->folder) {
|
||||||
|
return { folder, FullMsgId() };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (_state == WidgetState::Filtered) {
|
} else if (_state == WidgetState::Filtered) {
|
||||||
if (base::in_range(_filteredSelected, 0, _filterResults.size())) {
|
if (base::in_range(_filteredSelected, 0, _filterResults.size())) {
|
||||||
|
@ -1931,7 +2028,7 @@ void InnerWidget::peerSearchReceived(
|
||||||
const auto [i, ok] = _filterResultsGlobal.emplace(
|
const auto [i, ok] = _filterResultsGlobal.emplace(
|
||||||
peer,
|
peer,
|
||||||
std::move(row));
|
std::move(row));
|
||||||
_filterResults.push_back(i->second.get());
|
_filterResults.emplace_back(i->second.get());
|
||||||
} else {
|
} else {
|
||||||
LOG(("API Error: "
|
LOG(("API Error: "
|
||||||
"user %1 was not loaded in InnerWidget::peopleReceived()"
|
"user %1 was not loaded in InnerWidget::peopleReceived()"
|
||||||
|
@ -1957,7 +2054,7 @@ void InnerWidget::peerSearchReceived(
|
||||||
}
|
}
|
||||||
|
|
||||||
void InnerWidget::notify_historyMuteUpdated(History *history) {
|
void InnerWidget::notify_historyMuteUpdated(History *history) {
|
||||||
if (!_importantSwitch || !history->inChatList()) {
|
if (!Global::DialogsModeEnabled() || !history->inChatList()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
refreshDialog(history);
|
refreshDialog(history);
|
||||||
|
@ -1967,7 +2064,23 @@ Data::Folder *InnerWidget::shownFolder() const {
|
||||||
return _openedFolder;
|
return _openedFolder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool InnerWidget::needCollapsedRowsRefresh() const {
|
||||||
|
const auto archive = !shownDialogs()->empty()
|
||||||
|
? (*shownDialogs()->begin())->folder()
|
||||||
|
: nullptr;
|
||||||
|
const auto collapsedHasArchive = !_collapsedRows.empty()
|
||||||
|
&& (_collapsedRows.back()->folder != nullptr);
|
||||||
|
const auto archiveIsCollapsed = (archive != nullptr)
|
||||||
|
&& session().settings().archiveCollapsed();
|
||||||
|
return archiveIsCollapsed
|
||||||
|
? (!collapsedHasArchive || _skipByCollapsedRows != 1)
|
||||||
|
: (collapsedHasArchive || _skipByCollapsedRows != 0);
|
||||||
|
}
|
||||||
|
|
||||||
void InnerWidget::refresh(bool toTop) {
|
void InnerWidget::refresh(bool toTop) {
|
||||||
|
if (needCollapsedRowsRefresh()) {
|
||||||
|
return refreshWithCollapsedRows(toTop);
|
||||||
|
}
|
||||||
auto h = 0;
|
auto h = 0;
|
||||||
if (_state == WidgetState::Default) {
|
if (_state == WidgetState::Default) {
|
||||||
if (shownDialogs()->empty()) {
|
if (shownDialogs()->empty()) {
|
||||||
|
@ -2006,8 +2119,8 @@ void InnerWidget::clearMouseSelection(bool clearSelection) {
|
||||||
_lastMousePosition = std::nullopt;
|
_lastMousePosition = std::nullopt;
|
||||||
if (clearSelection) {
|
if (clearSelection) {
|
||||||
if (_state == WidgetState::Default) {
|
if (_state == WidgetState::Default) {
|
||||||
|
_collapsedSelected = -1;
|
||||||
_selected = nullptr;
|
_selected = nullptr;
|
||||||
_importantSwitchSelected = false;
|
|
||||||
} else if (_state == WidgetState::Filtered) {
|
} else if (_state == WidgetState::Filtered) {
|
||||||
_filteredSelected
|
_filteredSelected
|
||||||
= _peerSearchSelected
|
= _peerSearchSelected
|
||||||
|
@ -2116,41 +2229,40 @@ void InnerWidget::clearFilter() {
|
||||||
void InnerWidget::selectSkip(int32 direction) {
|
void InnerWidget::selectSkip(int32 direction) {
|
||||||
clearMouseSelection();
|
clearMouseSelection();
|
||||||
if (_state == WidgetState::Default) {
|
if (_state == WidgetState::Default) {
|
||||||
if (_importantSwitchSelected) {
|
const auto list = shownDialogs();
|
||||||
if (!shownDialogs()->empty() && direction > 0) {
|
if (_collapsedRows.empty() && list->size() <= _skipByCollapsedRows) {
|
||||||
_selected = *shownDialogs()->cbegin();
|
return;
|
||||||
_importantSwitchSelected = false;
|
}
|
||||||
|
if (_collapsedSelected < 0 && !_selected) {
|
||||||
|
if (!_collapsedRows.empty()) {
|
||||||
|
_collapsedSelected = 0;
|
||||||
} else {
|
} else {
|
||||||
return;
|
_selected = *(list->cbegin() + _skipByCollapsedRows);
|
||||||
}
|
|
||||||
} else if (!_selected) {
|
|
||||||
if (importantSwitchShown()) {
|
|
||||||
_importantSwitchSelected = true;
|
|
||||||
} else if (!shownDialogs()->empty() && direction > 0) {
|
|
||||||
_selected = *shownDialogs()->cbegin();
|
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else if (direction > 0) {
|
|
||||||
auto next = shownDialogs()->cfind(_selected);
|
|
||||||
if (++next != shownDialogs()->cend()) {
|
|
||||||
_selected = *next;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
auto prev = shownDialogs()->cfind(_selected);
|
auto cur = (_collapsedSelected >= 0)
|
||||||
if (prev != shownDialogs()->cbegin()) {
|
? _collapsedSelected
|
||||||
_selected = *(--prev);
|
: int(_collapsedRows.size()
|
||||||
} else if (importantSwitchShown()) {
|
+ (list->cfind(_selected) - list->cbegin() - _skipByCollapsedRows));
|
||||||
_importantSwitchSelected = true;
|
cur = snap(cur + direction, 0, static_cast<int>(_collapsedRows.size() + list->size() - _skipByCollapsedRows - 1));
|
||||||
|
if (cur < _collapsedRows.size()) {
|
||||||
|
_collapsedSelected = cur;
|
||||||
_selected = nullptr;
|
_selected = nullptr;
|
||||||
|
} else {
|
||||||
|
_collapsedSelected = -1;
|
||||||
|
_selected = *(list->cbegin() + _skipByCollapsedRows + cur - _collapsedRows.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (_importantSwitchSelected || _selected) {
|
if (_collapsedSelected >= 0 || _selected) {
|
||||||
int fromY = _importantSwitchSelected ? 0 : (dialogsOffset() + _selected->pos() * st::dialogsRowHeight);
|
const auto fromY = (_collapsedSelected >= 0)
|
||||||
|
? (_collapsedSelected * st::dialogsImportantBarHeight)
|
||||||
|
: (dialogsOffset() + _selected->pos() * st::dialogsRowHeight);
|
||||||
emit mustScrollTo(fromY, fromY + st::dialogsRowHeight);
|
emit mustScrollTo(fromY, fromY + st::dialogsRowHeight);
|
||||||
}
|
}
|
||||||
} else if (_state == WidgetState::Filtered) {
|
} else if (_state == WidgetState::Filtered) {
|
||||||
if (_hashtagResults.empty() && _filterResults.empty() && _peerSearchResults.empty() && _searchResults.empty()) return;
|
if (_hashtagResults.empty() && _filterResults.empty() && _peerSearchResults.empty() && _searchResults.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if ((_hashtagSelected < 0 || _hashtagSelected >= _hashtagResults.size()) &&
|
if ((_hashtagSelected < 0 || _hashtagSelected >= _hashtagResults.size()) &&
|
||||||
(_filteredSelected < 0 || _filteredSelected >= _filterResults.size()) &&
|
(_filteredSelected < 0 || _filteredSelected >= _filterResults.size()) &&
|
||||||
(_peerSearchSelected < 0 || _peerSearchSelected >= _peerSearchResults.size()) &&
|
(_peerSearchSelected < 0 || _peerSearchSelected >= _peerSearchResults.size()) &&
|
||||||
|
@ -2232,9 +2344,9 @@ void InnerWidget::selectSkipPage(int32 pixels, int32 direction) {
|
||||||
int toSkip = pixels / int(st::dialogsRowHeight);
|
int toSkip = pixels / int(st::dialogsRowHeight);
|
||||||
if (_state == WidgetState::Default) {
|
if (_state == WidgetState::Default) {
|
||||||
if (!_selected) {
|
if (!_selected) {
|
||||||
if (direction > 0 && !shownDialogs()->empty()) {
|
if (direction > 0 && shownDialogs()->size() > _skipByCollapsedRows) {
|
||||||
_selected = *shownDialogs()->cbegin();
|
_selected = *(shownDialogs()->cbegin() + _skipByCollapsedRows);
|
||||||
_importantSwitchSelected = false;
|
_collapsedSelected = -1;
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2244,16 +2356,18 @@ void InnerWidget::selectSkipPage(int32 pixels, int32 direction) {
|
||||||
_selected = *i;
|
_selected = *i;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (auto i = shownDialogs()->cfind(_selected), b = shownDialogs()->cbegin(); i != b && (toSkip--);) {
|
for (auto i = shownDialogs()->cfind(_selected), b = shownDialogs()->cbegin(); i != b && (*i)->pos() > _skipByCollapsedRows && (toSkip--);) {
|
||||||
_selected = *(--i);
|
_selected = *(--i);
|
||||||
}
|
}
|
||||||
if (toSkip && importantSwitchShown()) {
|
if (toSkip && !_collapsedRows.empty()) {
|
||||||
_importantSwitchSelected = true;
|
_collapsedSelected = std::max(int(_collapsedRows.size()) - toSkip, 0);
|
||||||
_selected = nullptr;
|
_selected = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (_importantSwitchSelected || _selected) {
|
if (_collapsedSelected >= 0 || _selected) {
|
||||||
int fromY = (_importantSwitchSelected ? 0 : (dialogsOffset() + _selected->pos() * st::dialogsRowHeight));
|
const auto fromY = (_collapsedSelected >= 0)
|
||||||
|
? (_collapsedSelected * st::dialogsImportantBarHeight)
|
||||||
|
: (dialogsOffset() + _selected->pos() * st::dialogsRowHeight);
|
||||||
emit mustScrollTo(fromY, fromY + st::dialogsRowHeight);
|
emit mustScrollTo(fromY, fromY + st::dialogsRowHeight);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -2317,12 +2431,23 @@ void InnerWidget::loadPeerPhotos() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool InnerWidget::switchImportantChats() {
|
bool InnerWidget::chooseCollapsedRow() {
|
||||||
if (!_importantSwitchSelected
|
if (_state != WidgetState::Default) {
|
||||||
|| !importantSwitchShown()
|
return false;
|
||||||
|| (_state != WidgetState::Default)) {
|
} else if ((_collapsedSelected < 0)
|
||||||
|
|| (_collapsedSelected >= _collapsedRows.size())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
const auto &row = _collapsedRows[_collapsedSelected];
|
||||||
|
if (row->folder) {
|
||||||
|
_controller->openFolder(row->folder);
|
||||||
|
} else {
|
||||||
|
switchImportantChats();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InnerWidget::switchImportantChats() {
|
||||||
clearSelection();
|
clearSelection();
|
||||||
if (Global::DialogsMode() == Mode::All) {
|
if (Global::DialogsMode() == Mode::All) {
|
||||||
Global::SetDialogsMode(Mode::Important);
|
Global::SetDialogsMode(Mode::Important);
|
||||||
|
@ -2331,9 +2456,8 @@ bool InnerWidget::switchImportantChats() {
|
||||||
}
|
}
|
||||||
_mode = Global::DialogsMode();
|
_mode = Global::DialogsMode();
|
||||||
Local::writeUserSettings();
|
Local::writeUserSettings();
|
||||||
refresh();
|
refreshWithCollapsedRows(true);
|
||||||
_importantSwitchSelected = true;
|
_collapsedSelected = 0;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool InnerWidget::chooseHashtag() {
|
bool InnerWidget::chooseHashtag() {
|
||||||
|
@ -2404,7 +2528,7 @@ ChosenRow InnerWidget::computeChosenRow() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool InnerWidget::chooseRow() {
|
bool InnerWidget::chooseRow() {
|
||||||
if (switchImportantChats()) {
|
if (chooseCollapsedRow()) {
|
||||||
return true;
|
return true;
|
||||||
} else if (chooseHashtag()) {
|
} else if (chooseHashtag()) {
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -146,7 +146,7 @@ protected:
|
||||||
void contextMenuEvent(QContextMenuEvent *e) override;
|
void contextMenuEvent(QContextMenuEvent *e) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct ImportantSwitch;
|
struct CollapsedRow;
|
||||||
struct HashtagResult;
|
struct HashtagResult;
|
||||||
struct PeerSearchResult;
|
struct PeerSearchResult;
|
||||||
|
|
||||||
|
@ -161,7 +161,11 @@ private:
|
||||||
|
|
||||||
void dialogRowReplaced(Row *oldRow, Row *newRow);
|
void dialogRowReplaced(Row *oldRow, Row *newRow);
|
||||||
|
|
||||||
bool switchImportantChats();
|
void repaintCollapsedFolderRow(not_null<Data::Folder*> folder);
|
||||||
|
void refreshWithCollapsedRows(bool toTop = false);
|
||||||
|
bool needCollapsedRowsRefresh() const;
|
||||||
|
bool chooseCollapsedRow();
|
||||||
|
void switchImportantChats();
|
||||||
bool chooseHashtag();
|
bool chooseHashtag();
|
||||||
ChosenRow computeChosenRow() const;
|
ChosenRow computeChosenRow() const;
|
||||||
bool isSearchResultActive(
|
bool isSearchResultActive(
|
||||||
|
@ -173,14 +177,14 @@ private:
|
||||||
void clearIrrelevantState();
|
void clearIrrelevantState();
|
||||||
void selectByMouse(QPoint globalPosition);
|
void selectByMouse(QPoint globalPosition);
|
||||||
void loadPeerPhotos();
|
void loadPeerPhotos();
|
||||||
void setImportantSwitchPressed(bool pressed);
|
void setCollapsedPressed(int pressed);
|
||||||
void setPressed(Row *pressed);
|
void setPressed(Row *pressed);
|
||||||
void setHashtagPressed(int pressed);
|
void setHashtagPressed(int pressed);
|
||||||
void setFilteredPressed(int pressed);
|
void setFilteredPressed(int pressed);
|
||||||
void setPeerSearchPressed(int pressed);
|
void setPeerSearchPressed(int pressed);
|
||||||
void setSearchedPressed(int pressed);
|
void setSearchedPressed(int pressed);
|
||||||
bool isPressed() const {
|
bool isPressed() const {
|
||||||
return _importantSwitchPressed
|
return (_collapsedPressed >= 0)
|
||||||
|| _pressed
|
|| _pressed
|
||||||
|| (_hashtagPressed >= 0)
|
|| (_hashtagPressed >= 0)
|
||||||
|| (_filteredPressed >= 0)
|
|| (_filteredPressed >= 0)
|
||||||
|
@ -188,7 +192,7 @@ private:
|
||||||
|| (_searchedPressed >= 0);
|
|| (_searchedPressed >= 0);
|
||||||
}
|
}
|
||||||
bool isSelected() const {
|
bool isSelected() const {
|
||||||
return _importantSwitchSelected
|
return (_collapsedSelected >= 0)
|
||||||
|| _selected
|
|| _selected
|
||||||
|| (_hashtagSelected >= 0)
|
|| (_hashtagSelected >= 0)
|
||||||
|| (_filteredSelected >= 0)
|
|| (_filteredSelected >= 0)
|
||||||
|
@ -227,15 +231,21 @@ private:
|
||||||
UpdateRowSections sections = UpdateRowSection::All);
|
UpdateRowSections sections = UpdateRowSection::All);
|
||||||
void fillSupportSearchMenu(not_null<Ui::PopupMenu*> menu);
|
void fillSupportSearchMenu(not_null<Ui::PopupMenu*> menu);
|
||||||
|
|
||||||
bool importantSwitchShown() const;
|
|
||||||
int dialogsOffset() const;
|
int dialogsOffset() const;
|
||||||
int proxyPromotedCount() const;
|
int fixedOnTopCount() const;
|
||||||
int pinnedOffset() const;
|
int pinnedOffset() const;
|
||||||
int filteredOffset() const;
|
int filteredOffset() const;
|
||||||
int peerSearchOffset() const;
|
int peerSearchOffset() const;
|
||||||
int searchedOffset() const;
|
int searchedOffset() const;
|
||||||
int searchInChatSkip() const;
|
int searchInChatSkip() const;
|
||||||
|
|
||||||
|
void paintCollapsedRows(
|
||||||
|
Painter &p,
|
||||||
|
QRect clip) const;
|
||||||
|
void paintCollapsedRow(
|
||||||
|
Painter &p,
|
||||||
|
not_null<const CollapsedRow*> row,
|
||||||
|
bool selected) const;
|
||||||
void paintPeerSearchResult(
|
void paintPeerSearchResult(
|
||||||
Painter &p,
|
Painter &p,
|
||||||
not_null<const PeerSearchResult*> result,
|
not_null<const PeerSearchResult*> result,
|
||||||
|
@ -290,9 +300,10 @@ private:
|
||||||
|
|
||||||
Data::Folder *_openedFolder = nullptr;
|
Data::Folder *_openedFolder = nullptr;
|
||||||
|
|
||||||
std::unique_ptr<ImportantSwitch> _importantSwitch;
|
std::vector<std::unique_ptr<CollapsedRow>> _collapsedRows;
|
||||||
bool _importantSwitchSelected = false;
|
int _collapsedSelected = -1;
|
||||||
bool _importantSwitchPressed = false;
|
int _collapsedPressed = -1;
|
||||||
|
int _skipByCollapsedRows = 0;
|
||||||
Row *_selected = nullptr;
|
Row *_selected = nullptr;
|
||||||
Row *_pressed = nullptr;
|
Row *_pressed = nullptr;
|
||||||
|
|
||||||
|
|
|
@ -841,26 +841,21 @@ QRect RowPainter::sendActionAnimationRect(int animationWidth, int animationHeigh
|
||||||
return QRect(nameleft, texttop, textUpdated ? namewidth : animationWidth, animationHeight);
|
return QRect(nameleft, texttop, textUpdated ? namewidth : animationWidth, animationHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
void paintImportantSwitch(Painter &p, Mode current, int fullWidth, bool selected) {
|
void PaintCollapsedRow(Painter &p, const RippleRow &row, const QString &text, int unread, int fullWidth, bool selected) {
|
||||||
p.fillRect(0, 0, fullWidth, st::dialogsImportantBarHeight, selected ? st::dialogsBgOver : st::dialogsBg);
|
p.fillRect(0, 0, fullWidth, st::dialogsImportantBarHeight, selected ? st::dialogsBgOver : st::dialogsBg);
|
||||||
|
|
||||||
|
row.paintRipple(p, 0, 0, fullWidth);
|
||||||
|
|
||||||
p.setFont(st::semiboldFont);
|
p.setFont(st::semiboldFont);
|
||||||
p.setPen(st::dialogsNameFg);
|
p.setPen(st::dialogsNameFg);
|
||||||
|
|
||||||
const auto unreadTop = (st::dialogsImportantBarHeight - st::dialogsUnreadHeight) / 2;
|
const auto unreadTop = (st::dialogsImportantBarHeight - st::dialogsUnreadHeight) / 2;
|
||||||
const auto mutedHidden = (current == Dialogs::Mode::Important);
|
|
||||||
const auto text = lang(mutedHidden
|
|
||||||
? lng_dialogs_show_all_chats
|
|
||||||
: lng_dialogs_hide_muted_chats);
|
|
||||||
const auto textBaseline = unreadTop
|
const auto textBaseline = unreadTop
|
||||||
+ (st::dialogsUnreadHeight - st::dialogsUnreadFont->height) / 2
|
+ (st::dialogsUnreadHeight - st::dialogsUnreadFont->height) / 2
|
||||||
+ st::dialogsUnreadFont->ascent;
|
+ st::dialogsUnreadFont->ascent;
|
||||||
p.drawText(st::dialogsPadding.x(), textBaseline, text);
|
p.drawText(st::dialogsPadding.x(), textBaseline, text);
|
||||||
|
|
||||||
if (!mutedHidden) {
|
if (unread) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (const auto unread = Auth().data().unreadOnlyMutedBadge()) {
|
|
||||||
const auto unreadRight = fullWidth - st::dialogsPadding.x();
|
const auto unreadRight = fullWidth - st::dialogsPadding.x();
|
||||||
UnreadBadgeStyle st;
|
UnreadBadgeStyle st;
|
||||||
st.muted = true;
|
st.muted = true;
|
||||||
|
|
|
@ -11,6 +11,7 @@ namespace Dialogs {
|
||||||
|
|
||||||
class Row;
|
class Row;
|
||||||
class FakeRow;
|
class FakeRow;
|
||||||
|
class RippleRow;
|
||||||
|
|
||||||
namespace Layout {
|
namespace Layout {
|
||||||
|
|
||||||
|
@ -48,9 +49,11 @@ public:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void paintImportantSwitch(
|
void PaintCollapsedRow(
|
||||||
Painter &p,
|
Painter &p,
|
||||||
Mode current,
|
const RippleRow &row,
|
||||||
|
const QString &text,
|
||||||
|
int unread,
|
||||||
int fullWidth,
|
int fullWidth,
|
||||||
bool selected);
|
bool selected);
|
||||||
|
|
||||||
|
|
|
@ -84,6 +84,7 @@ public:
|
||||||
void fill();
|
void fill();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void addToggleCollapse();
|
||||||
//bool showInfo();
|
//bool showInfo();
|
||||||
//void addTogglePin();
|
//void addTogglePin();
|
||||||
//void addInfo();
|
//void addInfo();
|
||||||
|
@ -91,10 +92,10 @@ private:
|
||||||
//void addNotifications();
|
//void addNotifications();
|
||||||
//void addUngroup();
|
//void addUngroup();
|
||||||
|
|
||||||
//not_null<Controller*> _controller;
|
not_null<Controller*> _controller;
|
||||||
//not_null<Data::Folder*> _folder;
|
not_null<Data::Folder*> _folder;
|
||||||
//const PeerMenuCallback &_addAction;
|
const PeerMenuCallback &_addAction;
|
||||||
//PeerMenuSource _source;
|
PeerMenuSource _source;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -534,54 +535,33 @@ FolderFiller::FolderFiller(
|
||||||
not_null<Controller*> controller,
|
not_null<Controller*> controller,
|
||||||
not_null<Data::Folder*> folder,
|
not_null<Data::Folder*> folder,
|
||||||
const PeerMenuCallback &addAction,
|
const PeerMenuCallback &addAction,
|
||||||
PeerMenuSource source) {
|
PeerMenuSource source)
|
||||||
//: _controller(controller)
|
: _controller(controller)
|
||||||
//, _folder(folder)
|
, _folder(folder)
|
||||||
//, _addAction(addAction)
|
, _addAction(addAction)
|
||||||
//, _source(source) {
|
, _source(source) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void FolderFiller::fill() { // #TODO archive
|
void FolderFiller::fill() {
|
||||||
//if (_source == PeerMenuSource::ChatsList) {
|
if (_source == PeerMenuSource::ChatsList) {
|
||||||
// addTogglePin();
|
addToggleCollapse();
|
||||||
//}
|
}
|
||||||
//if (showInfo()) {
|
}
|
||||||
// addInfo();
|
|
||||||
//}
|
void FolderFiller::addToggleCollapse() {
|
||||||
//addNotifications();
|
if (_folder->id() != Data::Folder::kId) {
|
||||||
//if (_source == PeerMenuSource::ChatsList) {
|
return;
|
||||||
// addSearch();
|
}
|
||||||
//}
|
const auto controller = _controller;
|
||||||
//addUngroup();
|
const auto hidden = controller->session().settings().archiveCollapsed();
|
||||||
|
const auto text = lang(hidden
|
||||||
|
? lng_context_archive_expand
|
||||||
|
: lng_context_archive_collapse);
|
||||||
|
_addAction(text, [=] {
|
||||||
|
controller->session().settings().setArchiveCollapsed(!hidden);
|
||||||
|
controller->session().saveSettingsDelayed();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
//
|
|
||||||
//bool FolderFiller::showInfo() {
|
|
||||||
// if (_source == PeerMenuSource::Profile) {
|
|
||||||
// return false;
|
|
||||||
// } else if (_controller->activeChatCurrent().feed() != _feed) {
|
|
||||||
// return true;
|
|
||||||
// } else if (!Adaptive::ThreeColumn()) {
|
|
||||||
// return true;
|
|
||||||
// } else if (
|
|
||||||
// !Auth().settings().thirdSectionInfoEnabled() &&
|
|
||||||
// !Auth().settings().tabbedReplacedWithInfo()) {
|
|
||||||
// return true;
|
|
||||||
// }
|
|
||||||
// return false;
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//void FolderFiller::addTogglePin() {
|
|
||||||
// const auto feed = _feed;
|
|
||||||
// const auto isPinned = feed->isPinnedDialog();
|
|
||||||
// const auto pinText = [](bool isPinned) {
|
|
||||||
// return lang(isPinned
|
|
||||||
// ? lng_context_unpin_from_top
|
|
||||||
// : lng_context_pin_to_top);
|
|
||||||
// };
|
|
||||||
// _addAction(pinText(isPinned), [=] {
|
|
||||||
// TogglePinnedDialog(feed);
|
|
||||||
// });
|
|
||||||
//}
|
|
||||||
//
|
//
|
||||||
//void FolderFiller::addInfo() {
|
//void FolderFiller::addInfo() {
|
||||||
// auto controller = _controller;
|
// auto controller = _controller;
|
||||||
|
|
Loading…
Reference in New Issue