diff --git a/Telegram/SourceFiles/core/kotato_settings.cpp b/Telegram/SourceFiles/core/kotato_settings.cpp index abcd34807..680cd94ff 100644 --- a/Telegram/SourceFiles/core/kotato_settings.cpp +++ b/Telegram/SourceFiles/core/kotato_settings.cpp @@ -212,6 +212,14 @@ bool Manager::readCustomFile() { } } + + const auto settingsChatListLinesIt = settings.constFind(qsl("chat_list_lines")); + if (settingsChatListLinesIt != settings.constEnd()) { + const auto settingsChatListLines = (*settingsChatListLinesIt).toInt(); + if (settingsChatListLines >= 1 || settingsChatListLines <= 2) { + cSetDialogListLines(settingsChatListLines); + } + } return true; } @@ -246,6 +254,7 @@ void Manager::writeDefaultFile() { settings.insert(qsl("show_chat_id"), cShowChatId()); settings.insert(qsl("net_speed_boost"), QJsonValue(QJsonValue::Null)); settings.insert(qsl("show_phone_in_drawer"), cShowPhoneInDrawer()); + settings.insert(qsl("chat_list_lines"), cDialogListLines()); auto settingsScales = QJsonArray(); settings.insert(qsl("scales"), settingsScales); @@ -298,6 +307,7 @@ void Manager::writeCurrentSettings() { settings.insert(qsl("show_chat_id"), cShowChatId()); settings.insert(qsl("net_speed_boost"), cNetSpeedBoost()); settings.insert(qsl("show_phone_in_drawer"), cShowPhoneInDrawer()); + settings.insert(qsl("chat_list_lines"), cDialogListLines()); auto settingsScales = QJsonArray(); auto currentScales = cInterfaceScales(); diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp index a0de1069c..35a577dcc 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp @@ -53,6 +53,14 @@ namespace { constexpr auto kHashtagResultsLimit = 5; constexpr auto kStartReorderThreshold = 30; +inline int DialogsRowHeight() { + return (cDialogListLines() == 1 ? st::dialogsImportantBarHeight : st::dialogsRowHeight); +} + +inline int DialogsPhotoSize() { + return (cDialogListLines() == 1 ? st::dialogsUnreadHeight : st::dialogsPhotoSize); +} + int FixedOnTopDialogsCount(not_null list) { auto result = 0; for (const auto row : *list) { @@ -287,7 +295,7 @@ void InnerWidget::refreshWithCollapsedRows(bool toTop) { ? (*list->begin())->folder() : nullptr; const auto inMainMenu = session().settings().archiveInMainMenu(); - if (archive && (session().settings().archiveCollapsed() || inMainMenu)) { + if (archive && (session().settings().archiveCollapsed() || inMainMenu || cDialogListLines() == 1)) { if (_selected && _selected->folder() == archive) { _selected = nullptr; } @@ -315,7 +323,7 @@ void InnerWidget::refreshWithCollapsedRows(bool toTop) { int InnerWidget::dialogsOffset() const { return _collapsedRows.size() * st::dialogsImportantBarHeight - - _skipTopDialogs * st::dialogsRowHeight; + - _skipTopDialogs * DialogsRowHeight(); } int InnerWidget::fixedOnTopCount() const { @@ -331,7 +339,7 @@ int InnerWidget::fixedOnTopCount() const { } int InnerWidget::pinnedOffset() const { - return dialogsOffset() + fixedOnTopCount() * st::dialogsRowHeight; + return dialogsOffset() + fixedOnTopCount() * DialogsRowHeight(); } int InnerWidget::filteredOffset() const { @@ -339,11 +347,11 @@ int InnerWidget::filteredOffset() const { } int InnerWidget::peerSearchOffset() const { - return filteredOffset() + (_filterResults.size() * st::dialogsRowHeight) + st::searchedBarHeight; + return filteredOffset() + (_filterResults.size() * DialogsRowHeight()) + st::searchedBarHeight; } int InnerWidget::searchedOffset() const { - auto result = peerSearchOffset() + (_peerSearchResults.empty() ? 0 : ((_peerSearchResults.size() * st::dialogsRowHeight) + st::searchedBarHeight)); + auto result = peerSearchOffset() + (_peerSearchResults.empty() ? 0 : ((_peerSearchResults.size() * DialogsRowHeight()) + st::searchedBarHeight)); if (_searchInChat) { result += searchInChatSkip(); } @@ -394,7 +402,7 @@ void InnerWidget::paintEvent(QPaintEvent *e) { const auto rows = shownDialogs(); const auto &list = rows->all(); - const auto otherStart = std::max(int(rows->size()) - _skipTopDialogs, 0) * st::dialogsRowHeight; + const auto otherStart = std::max(int(rows->size()) - _skipTopDialogs, 0) * DialogsRowHeight(); const auto active = activeEntry.key; const auto selected = _menuRow.key ? _menuRow.key @@ -409,7 +417,7 @@ void InnerWidget::paintEvent(QPaintEvent *e) { const auto skip = dialogsOffset(); auto reorderingPinned = (_aboveIndex >= 0 && !_pinnedRows.empty()); if (reorderingPinned) { - dialogsClip = dialogsClip.marginsAdded(QMargins(0, st::dialogsRowHeight, 0, st::dialogsRowHeight)); + dialogsClip = dialogsClip.marginsAdded(QMargins(0, DialogsRowHeight(), 0, DialogsRowHeight())); } const auto promoted = fixedOnTopCount(); @@ -437,7 +445,7 @@ void InnerWidget::paintEvent(QPaintEvent *e) { } }; - auto i = list.cfind(dialogsClip.top() - skip, st::dialogsRowHeight); + auto i = list.cfind(dialogsClip.top() - skip, DialogsRowHeight()); while (i != list.cend() && (*i)->pos() < _skipTopDialogs) { ++i; } @@ -446,13 +454,13 @@ void InnerWidget::paintEvent(QPaintEvent *e) { // If we're reordering pinned chats we need to fill this area background first. if (reorderingPinned) { - p.fillRect(0, (promoted - _skipTopDialogs) * st::dialogsRowHeight, fullWidth, st::dialogsRowHeight * _pinnedRows.size(), st::dialogsBg); + p.fillRect(0, (promoted - _skipTopDialogs) * DialogsRowHeight(), fullWidth, DialogsRowHeight() * _pinnedRows.size(), st::dialogsBg); } - p.translate(0, (lastPaintedPos - _skipTopDialogs) * st::dialogsRowHeight); + p.translate(0, (lastPaintedPos - _skipTopDialogs) * DialogsRowHeight()); for (auto e = list.cend(); i != e; ++i) { auto row = (*i); - if ((lastPaintedPos - _skipTopDialogs) * st::dialogsRowHeight >= dialogsClip.top() - skip + dialogsClip.height()) { + if ((lastPaintedPos - _skipTopDialogs) * DialogsRowHeight() >= dialogsClip.top() - skip + dialogsClip.height()) { break; } @@ -462,7 +470,7 @@ void InnerWidget::paintEvent(QPaintEvent *e) { paintDialog(row); } - p.translate(0, st::dialogsRowHeight); + p.translate(0, DialogsRowHeight()); ++lastPaintedPos; } @@ -471,9 +479,9 @@ void InnerWidget::paintEvent(QPaintEvent *e) { auto i = list.cfind(promoted + _aboveIndex, 1); auto pos = (i == list.cend()) ? -1 : (*i)->pos(); if (pos == promoted + _aboveIndex) { - p.translate(0, (pos - lastPaintedPos) * st::dialogsRowHeight); + p.translate(0, (pos - lastPaintedPos) * DialogsRowHeight()); paintDialog(*i); - p.translate(0, (lastPaintedPos - pos) * st::dialogsRowHeight); + p.translate(0, (lastPaintedPos - pos) * DialogsRowHeight()); } } } @@ -536,9 +544,9 @@ void InnerWidget::paintEvent(QPaintEvent *e) { } if (!_filterResults.empty()) { auto skip = filteredOffset(); - auto from = floorclamp(r.y() - skip, st::dialogsRowHeight, 0, _filterResults.size()); - auto to = ceilclamp(r.y() + r.height() - skip, st::dialogsRowHeight, 0, _filterResults.size()); - p.translate(0, from * st::dialogsRowHeight); + auto from = floorclamp(r.y() - skip, DialogsRowHeight(), 0, _filterResults.size()); + auto to = ceilclamp(r.y() + r.height() - skip, DialogsRowHeight(), 0, _filterResults.size()); + p.translate(0, from * DialogsRowHeight()); if (from < _filterResults.size()) { for (; from < to; ++from) { const auto row = _filterResults[from]; @@ -557,7 +565,7 @@ void InnerWidget::paintEvent(QPaintEvent *e) { active, selected, ms); - p.translate(0, st::dialogsRowHeight); + p.translate(0, DialogsRowHeight()); } } } @@ -570,9 +578,9 @@ void InnerWidget::paintEvent(QPaintEvent *e) { p.translate(0, st::searchedBarHeight); auto skip = peerSearchOffset(); - auto from = floorclamp(r.y() - skip, st::dialogsRowHeight, 0, _peerSearchResults.size()); - auto to = ceilclamp(r.y() + r.height() - skip, st::dialogsRowHeight, 0, _peerSearchResults.size()); - p.translate(0, from * st::dialogsRowHeight); + auto from = floorclamp(r.y() - skip, DialogsRowHeight(), 0, _peerSearchResults.size()); + auto to = ceilclamp(r.y() + r.height() - skip, DialogsRowHeight(), 0, _peerSearchResults.size()); + p.translate(0, from * DialogsRowHeight()); if (from < _peerSearchResults.size()) { const auto activePeer = activeEntry.key.peer(); for (; from < to; ++from) { @@ -586,7 +594,7 @@ void InnerWidget::paintEvent(QPaintEvent *e) { ? _peerSearchPressed : _peerSearchSelected)); paintPeerSearchResult(p, result.get(), fullWidth, active, selected); - p.translate(0, st::dialogsRowHeight); + p.translate(0, DialogsRowHeight()); } } } @@ -629,9 +637,9 @@ void InnerWidget::paintEvent(QPaintEvent *e) { p.translate(0, st::searchedBarHeight); auto skip = searchedOffset(); - auto from = floorclamp(r.y() - skip, st::dialogsRowHeight, 0, _searchResults.size()); - auto to = ceilclamp(r.y() + r.height() - skip, st::dialogsRowHeight, 0, _searchResults.size()); - p.translate(0, from * st::dialogsRowHeight); + auto from = floorclamp(r.y() - skip, DialogsRowHeight(), 0, _searchResults.size()); + auto to = ceilclamp(r.y() + r.height() - skip, DialogsRowHeight(), 0, _searchResults.size()); + p.translate(0, from * DialogsRowHeight()); if (from < _searchResults.size()) { for (; from < to; ++from) { const auto &result = _searchResults[from]; @@ -649,7 +657,7 @@ void InnerWidget::paintEvent(QPaintEvent *e) { selected, ms, showUnreadInSearchResults); - p.translate(0, st::dialogsRowHeight); + p.translate(0, DialogsRowHeight()); } } } @@ -721,7 +729,7 @@ void InnerWidget::paintPeerSearchResult( int fullWidth, bool active, bool selected) const { - QRect fullRect(0, 0, fullWidth, st::dialogsRowHeight); + QRect fullRect(0, 0, fullWidth, DialogsRowHeight()); p.fillRect(fullRect, active ? st::dialogsBgActive : (selected ? st::dialogsBgOver : st::dialogsBg)); if (!active) { result->row.paintRipple(p, 0, 0, fullWidth); @@ -729,9 +737,9 @@ void InnerWidget::paintPeerSearchResult( auto peer = result->peer; auto userpicPeer = (peer->migrateTo() ? peer->migrateTo() : peer); - userpicPeer->paintUserpicLeft(p, st::dialogsPadding.x(), st::dialogsPadding.y(), width(), st::dialogsPhotoSize); + userpicPeer->paintUserpicLeft(p, st::dialogsPadding.x(), st::dialogsPadding.y(), width(), DialogsPhotoSize()); - auto nameleft = st::dialogsPadding.x() + st::dialogsPhotoSize + st::dialogsPhotoPadding; + auto nameleft = st::dialogsPadding.x() + DialogsPhotoSize() + st::dialogsPhotoPadding; auto namewidth = fullWidth - nameleft - st::dialogsPadding.x(); QRect rectForName(nameleft, st::dialogsPadding.y() + st::dialogsNameTop, namewidth, st::msgNameFont->height); @@ -946,7 +954,7 @@ void InnerWidget::selectByMouse(QPoint globalPosition) { : (mouseY >= offset) ? shownDialogs()->rowAtY( mouseY - offset, - st::dialogsRowHeight) + DialogsRowHeight()) : nullptr; if (_selected != selected || _collapsedSelected != collapsedSelected) { updateSelectedRow(); @@ -977,7 +985,7 @@ void InnerWidget::selectByMouse(QPoint globalPosition) { } if (!_filterResults.empty()) { auto skip = filteredOffset(); - auto filteredSelected = (mouseY >= skip) ? ((mouseY - skip) / st::dialogsRowHeight) : -1; + auto filteredSelected = (mouseY >= skip) ? ((mouseY - skip) / DialogsRowHeight()) : -1; if (filteredSelected < 0 || filteredSelected >= _filterResults.size()) { filteredSelected = -1; } @@ -989,7 +997,7 @@ void InnerWidget::selectByMouse(QPoint globalPosition) { } if (!_peerSearchResults.empty()) { auto skip = peerSearchOffset(); - auto peerSearchSelected = (mouseY >= skip) ? ((mouseY - skip) / st::dialogsRowHeight) : -1; + auto peerSearchSelected = (mouseY >= skip) ? ((mouseY - skip) / DialogsRowHeight()) : -1; if (peerSearchSelected < 0 || peerSearchSelected >= _peerSearchResults.size()) { peerSearchSelected = -1; } @@ -1001,7 +1009,7 @@ void InnerWidget::selectByMouse(QPoint globalPosition) { } if (!_waitingForSearch && !_searchResults.empty()) { auto skip = searchedOffset(); - auto searchedSelected = (mouseY >= skip) ? ((mouseY - skip) / st::dialogsRowHeight) : -1; + auto searchedSelected = (mouseY >= skip) ? ((mouseY - skip) / DialogsRowHeight()) : -1; if (searchedSelected < 0 || searchedSelected >= _searchResults.size()) { searchedSelected = -1; } @@ -1035,7 +1043,7 @@ void InnerWidget::mousePressEvent(QMouseEvent *e) { }); } else if (_pressed) { auto row = _pressed; - row->addRipple(e->pos() - QPoint(0, dialogsOffset() + _pressed->pos() * st::dialogsRowHeight), QSize(width(), st::dialogsRowHeight), [this, row] { + row->addRipple(e->pos() - QPoint(0, dialogsOffset() + _pressed->pos() * DialogsRowHeight()), QSize(width(), DialogsRowHeight()), [this, row] { if (!_pinnedShiftAnimation.animating()) { row->entry()->updateChatListEntry(); } @@ -1050,20 +1058,20 @@ void InnerWidget::mousePressEvent(QMouseEvent *e) { const auto row = _filterResults[_filteredPressed]; const auto list = _mode; row->addRipple( - e->pos() - QPoint(0, filteredOffset() + _filteredPressed * st::dialogsRowHeight), - QSize(width(), st::dialogsRowHeight), + e->pos() - QPoint(0, filteredOffset() + _filteredPressed * DialogsRowHeight()), + QSize(width(), DialogsRowHeight()), [=] { repaintDialogRow(list, row); }); } else if (base::in_range(_peerSearchPressed, 0, _peerSearchResults.size())) { auto &result = _peerSearchResults[_peerSearchPressed]; auto row = &result->row; row->addRipple( - e->pos() - QPoint(0, peerSearchOffset() + _peerSearchPressed * st::dialogsRowHeight), - QSize(width(), st::dialogsRowHeight), + e->pos() - QPoint(0, peerSearchOffset() + _peerSearchPressed * DialogsRowHeight()), + QSize(width(), DialogsRowHeight()), [this, peer = result->peer] { updateSearchResult(peer); }); } else if (base::in_range(_searchedPressed, 0, _searchResults.size())) { auto &row = _searchResults[_searchedPressed]; - row->addRipple(e->pos() - QPoint(0, searchedOffset() + _searchedPressed * st::dialogsRowHeight), QSize(width(), st::dialogsRowHeight), [this, index = _searchedPressed] { - rtlupdate(0, searchedOffset() + index * st::dialogsRowHeight, width(), st::dialogsRowHeight); + row->addRipple(e->pos() - QPoint(0, searchedOffset() + _searchedPressed * DialogsRowHeight()), QSize(width(), DialogsRowHeight()), [this, index = _searchedPressed] { + rtlupdate(0, searchedOffset() + index * DialogsRowHeight(), width(), DialogsRowHeight()); }); } if (anim::Disabled() @@ -1182,7 +1190,7 @@ bool InnerWidget::updateReorderPinned(QPoint localPosition) { auto yaddWas = _pinnedRows[_draggingIndex].yadd.current(); auto shift = 0; auto now = crl::now(); - auto rowHeight = st::dialogsRowHeight; + auto rowHeight = DialogsRowHeight(); if (_dragStart.y() > localPosition.y() && _draggingIndex > 0) { shift = -floorclamp(_dragStart.y() - localPosition.y() + (rowHeight / 2), rowHeight, 0, _draggingIndex); @@ -1263,11 +1271,11 @@ bool InnerWidget::pinnedShiftAnimationCallback(crl::time now) { } if (updateMin >= 0) { auto top = pinnedOffset(); - auto updateFrom = top + st::dialogsRowHeight * (updateMin - 1); - auto updateHeight = st::dialogsRowHeight * (updateMax - updateMin + 3); + auto updateFrom = top + DialogsRowHeight() * (updateMin - 1); + auto updateHeight = DialogsRowHeight() * (updateMax - updateMin + 3); if (base::in_range(_aboveIndex, 0, _pinnedRows.size())) { // Always include currently dragged chat in its current and old positions. - auto aboveRowBottom = top + (_aboveIndex + 1) * st::dialogsRowHeight; + auto aboveRowBottom = top + (_aboveIndex + 1) * DialogsRowHeight(); auto aboveTopShift = qCeil(_pinnedRows[_aboveIndex].yadd.current()); accumulate_max(updateHeight, (aboveRowBottom - updateFrom) + _aboveTopShift); accumulate_max(updateHeight, (aboveRowBottom - updateFrom) + aboveTopShift); @@ -1441,7 +1449,7 @@ void InnerWidget::refreshDialog(Key key) { ? result.importantMoved : result.moved; - const auto rowHeight = st::dialogsRowHeight; + const auto rowHeight = DialogsRowHeight(); const auto from = dialogsOffset() + moved.from * rowHeight; const auto to = dialogsOffset() + moved.to * rowHeight; if (!_dragging @@ -1506,7 +1514,7 @@ int InnerWidget::defaultRowTop(not_null row) const { if (base::in_range(position, 0, _pinnedRows.size())) { top += qRound(_pinnedRows[position].yadd.current()); } - return top + position * st::dialogsRowHeight; + return top + position * DialogsRowHeight(); } void InnerWidget::repaintDialogRow( @@ -1517,7 +1525,7 @@ void InnerWidget::repaintDialogRow( if (const auto folder = row->folder()) { repaintCollapsedFolderRow(folder); } - update(0, defaultRowTop(row), width(), st::dialogsRowHeight); + update(0, defaultRowTop(row), width(), DialogsRowHeight()); } } else if (_state == WidgetState::Filtered) { if (list == Mode::All) { @@ -1525,9 +1533,9 @@ void InnerWidget::repaintDialogRow( if (_filterResults[i]->key() == row->key()) { update( 0, - filteredOffset() + i * st::dialogsRowHeight, + filteredOffset() + i * DialogsRowHeight(), width(), - st::dialogsRowHeight); + DialogsRowHeight()); break; } } @@ -1545,7 +1553,7 @@ void InnerWidget::updateSearchResult(not_null peer) { auto index = 0, add = peerSearchOffset(); for (const auto &result : _peerSearchResults) { if (result->peer == peer) { - rtlupdate(0, add + index * st::dialogsRowHeight, width(), st::dialogsRowHeight); + rtlupdate(0, add + index * DialogsRowHeight(), width(), DialogsRowHeight()); break; } ++index; @@ -1559,7 +1567,7 @@ void InnerWidget::updateDialogRow( QRect updateRect, UpdateRowSections sections) { if (updateRect.isEmpty()) { - updateRect = QRect(0, 0, width(), st::dialogsRowHeight); + updateRect = QRect(0, 0, width(), DialogsRowHeight()); } if (IsServerMsgId(-row.fullId.msg)) { if (const auto peer = row.key.peer()) { @@ -1591,7 +1599,7 @@ void InnerWidget::updateDialogRow( if (base::in_range(position, 0, _pinnedRows.size())) { top += qRound(_pinnedRows[position].yadd.current()); } - updateRow(top + position * st::dialogsRowHeight); + updateRow(top + position * DialogsRowHeight()); } } } else if (_state == WidgetState::Filtered) { @@ -1601,7 +1609,7 @@ void InnerWidget::updateDialogRow( auto index = 0; for (const auto result : _filterResults) { if (result->key() == row.key) { - updateRow(add + index * st::dialogsRowHeight); + updateRow(add + index * DialogsRowHeight()); break; } ++index; @@ -1614,7 +1622,7 @@ void InnerWidget::updateDialogRow( auto index = 0; for (const auto &result : _peerSearchResults) { if (result->peer == peer) { - updateRow(add + index * st::dialogsRowHeight); + updateRow(add + index * DialogsRowHeight()); break; } ++index; @@ -1627,7 +1635,7 @@ void InnerWidget::updateDialogRow( auto index = 0; for (const auto &result : _searchResults) { if (isSearchResultActive(result.get(), row)) { - updateRow(add + index * st::dialogsRowHeight); + updateRow(add + index * DialogsRowHeight()); break; } ++index; @@ -1652,9 +1660,9 @@ void InnerWidget::updateSelectedRow(Key key) { if (base::in_range(position, 0, _pinnedRows.size())) { top += qRound(_pinnedRows[position].yadd.current()); } - update(0, top + position * st::dialogsRowHeight, width(), st::dialogsRowHeight); + update(0, top + position * DialogsRowHeight(), width(), DialogsRowHeight()); } else if (_selected) { - update(0, dialogsOffset() + _selected->pos() * st::dialogsRowHeight, width(), st::dialogsRowHeight); + update(0, dialogsOffset() + _selected->pos() * DialogsRowHeight(), width(), DialogsRowHeight()); } else if (_collapsedSelected >= 0) { update(0, _collapsedSelected * st::dialogsImportantBarHeight, width(), st::dialogsImportantBarHeight); } @@ -1662,18 +1670,18 @@ void InnerWidget::updateSelectedRow(Key key) { if (key) { for (auto i = 0, l = int(_filterResults.size()); i != l; ++i) { if (_filterResults[i]->key() == key) { - update(0, filteredOffset() + i * st::dialogsRowHeight, width(), st::dialogsRowHeight); + update(0, filteredOffset() + i * DialogsRowHeight(), width(), DialogsRowHeight()); break; } } } else if (_hashtagSelected >= 0) { update(0, _hashtagSelected * st::mentionHeight, width(), st::mentionHeight); } else if (_filteredSelected >= 0) { - update(0, filteredOffset() + _filteredSelected * st::dialogsRowHeight, width(), st::dialogsRowHeight); + update(0, filteredOffset() + _filteredSelected * DialogsRowHeight(), width(), DialogsRowHeight()); } else if (_peerSearchSelected >= 0) { - update(0, peerSearchOffset() + _peerSearchSelected * st::dialogsRowHeight, width(), st::dialogsRowHeight); + update(0, peerSearchOffset() + _peerSearchSelected * DialogsRowHeight(), width(), DialogsRowHeight()); } else if (_searchedSelected >= 0) { - update(0, searchedOffset() + _searchedSelected * st::dialogsRowHeight, width(), st::dialogsRowHeight); + update(0, searchedOffset() + _searchedSelected * DialogsRowHeight(), width(), DialogsRowHeight()); } } } @@ -2154,7 +2162,7 @@ bool InnerWidget::needCollapsedRowsRefresh() const { const auto collapsedHasArchive = !_collapsedRows.empty() && (_collapsedRows.back()->folder != nullptr); const auto archiveIsCollapsed = (archive != nullptr) - && session().settings().archiveCollapsed(); + && (session().settings().archiveCollapsed() || cDialogListLines() == 1); const auto archiveIsInMainMenu = (archive != nullptr) && session().settings().archiveInMainMenu(); return archiveIsInMainMenu @@ -2178,15 +2186,15 @@ void InnerWidget::refresh(bool toTop) { if (!_addContactLnk->isHidden()) _addContactLnk->hide(); } } else { - h = dialogsOffset() + shownDialogs()->size() * st::dialogsRowHeight; + h = dialogsOffset() + shownDialogs()->size() * DialogsRowHeight(); if (!_addContactLnk->isHidden()) _addContactLnk->hide(); } } else if (_state == WidgetState::Filtered) { if (!_addContactLnk->isHidden()) _addContactLnk->hide(); if (_waitingForSearch) { - h = searchedOffset() + (_searchResults.size() * st::dialogsRowHeight) + ((_searchResults.empty() && !_searchInChat) ? -st::searchedBarHeight : 0); + h = searchedOffset() + (_searchResults.size() * DialogsRowHeight()) + ((_searchResults.empty() && !_searchInChat) ? -st::searchedBarHeight : 0); } else { - h = searchedOffset() + (_searchResults.size() * st::dialogsRowHeight); + h = searchedOffset() + (_searchResults.size() * DialogsRowHeight()); } } resize(width(), h); @@ -2339,8 +2347,8 @@ void InnerWidget::selectSkip(int32 direction) { if (_collapsedSelected >= 0 || _selected) { const auto fromY = (_collapsedSelected >= 0) ? (_collapsedSelected * st::dialogsImportantBarHeight) - : (dialogsOffset() + _selected->pos() * st::dialogsRowHeight); - emit mustScrollTo(fromY, fromY + st::dialogsRowHeight); + : (dialogsOffset() + _selected->pos() * DialogsRowHeight()); + emit mustScrollTo(fromY, fromY + DialogsRowHeight()); } } else if (_state == WidgetState::Filtered) { if (_hashtagResults.empty() && _filterResults.empty() && _peerSearchResults.empty() && _searchResults.empty()) { @@ -2385,11 +2393,11 @@ void InnerWidget::selectSkip(int32 direction) { if (base::in_range(_hashtagSelected, 0, _hashtagResults.size())) { emit mustScrollTo(_hashtagSelected * st::mentionHeight, (_hashtagSelected + 1) * st::mentionHeight); } else if (base::in_range(_filteredSelected, 0, _filterResults.size())) { - emit mustScrollTo(filteredOffset() + _filteredSelected * st::dialogsRowHeight, filteredOffset() + (_filteredSelected + 1) * st::dialogsRowHeight); + emit mustScrollTo(filteredOffset() + _filteredSelected * DialogsRowHeight(), filteredOffset() + (_filteredSelected + 1) * DialogsRowHeight()); } else if (base::in_range(_peerSearchSelected, 0, _peerSearchResults.size())) { - emit mustScrollTo(peerSearchOffset() + _peerSearchSelected * st::dialogsRowHeight + (_peerSearchSelected ? 0 : -st::searchedBarHeight), peerSearchOffset() + (_peerSearchSelected + 1) * st::dialogsRowHeight); + emit mustScrollTo(peerSearchOffset() + _peerSearchSelected * DialogsRowHeight() + (_peerSearchSelected ? 0 : -st::searchedBarHeight), peerSearchOffset() + (_peerSearchSelected + 1) * DialogsRowHeight()); } else { - emit mustScrollTo(searchedOffset() + _searchedSelected * st::dialogsRowHeight + (_searchedSelected ? 0 : -st::searchedBarHeight), searchedOffset() + (_searchedSelected + 1) * st::dialogsRowHeight); + emit mustScrollTo(searchedOffset() + _searchedSelected * DialogsRowHeight() + (_searchedSelected ? 0 : -st::searchedBarHeight), searchedOffset() + (_searchedSelected + 1) * DialogsRowHeight()); } } update(); @@ -2399,32 +2407,32 @@ void InnerWidget::scrollToEntry(const RowDescriptor &entry) { int32 fromY = -1; if (_state == WidgetState::Default) { if (auto row = shownDialogs()->getRow(entry.key)) { - fromY = dialogsOffset() + row->pos() * st::dialogsRowHeight; + fromY = dialogsOffset() + row->pos() * DialogsRowHeight(); } } else if (_state == WidgetState::Filtered) { for (int32 i = 0, c = _searchResults.size(); i < c; ++i) { if (isSearchResultActive(_searchResults[i].get(), entry)) { - fromY = searchedOffset() + i * st::dialogsRowHeight; + fromY = searchedOffset() + i * DialogsRowHeight(); break; } } if (fromY < 0) { for (auto i = 0, c = int(_filterResults.size()); i != c; ++i) { if (_filterResults[i]->key() == entry.key) { - fromY = filteredOffset() + (i * st::dialogsRowHeight); + fromY = filteredOffset() + (i * DialogsRowHeight()); break; } } } } if (fromY >= 0) { - emit mustScrollTo(fromY, fromY + st::dialogsRowHeight); + emit mustScrollTo(fromY, fromY + DialogsRowHeight()); } } void InnerWidget::selectSkipPage(int32 pixels, int32 direction) { clearMouseSelection(); - int toSkip = pixels / int(st::dialogsRowHeight); + int toSkip = pixels / int(DialogsRowHeight()); if (_state == WidgetState::Default) { if (!_selected) { if (direction > 0 && shownDialogs()->size() > _skipTopDialogs) { @@ -2450,8 +2458,8 @@ void InnerWidget::selectSkipPage(int32 pixels, int32 direction) { if (_collapsedSelected >= 0 || _selected) { const auto fromY = (_collapsedSelected >= 0) ? (_collapsedSelected * st::dialogsImportantBarHeight) - : (dialogsOffset() + _selected->pos() * st::dialogsRowHeight); - emit mustScrollTo(fromY, fromY + st::dialogsRowHeight); + : (dialogsOffset() + _selected->pos() * DialogsRowHeight()); + emit mustScrollTo(fromY, fromY + DialogsRowHeight()); } } else { return selectSkip(direction * toSkip); @@ -2466,10 +2474,10 @@ void InnerWidget::loadPeerPhotos() { auto yTo = _visibleTop + (_visibleBottom - _visibleTop) * (PreloadHeightsCount + 1); session().downloader().clearPriorities(); if (_state == WidgetState::Default) { - auto otherStart = shownDialogs()->size() * st::dialogsRowHeight; + auto otherStart = shownDialogs()->size() * DialogsRowHeight(); if (yFrom < otherStart) { - for (auto i = shownDialogs()->cfind(yFrom, st::dialogsRowHeight), end = shownDialogs()->cend(); i != end; ++i) { - if (((*i)->pos() * st::dialogsRowHeight) >= yTo) { + for (auto i = shownDialogs()->cfind(yFrom, DialogsRowHeight()), end = shownDialogs()->cend(); i != end; ++i) { + if (((*i)->pos() * DialogsRowHeight()) >= yTo) { break; } (*i)->entry()->loadUserpic(); @@ -2480,10 +2488,10 @@ void InnerWidget::loadPeerPhotos() { } yTo -= otherStart; } else if (_state == WidgetState::Filtered) { - int32 from = (yFrom - filteredOffset()) / st::dialogsRowHeight; + int32 from = (yFrom - filteredOffset()) / DialogsRowHeight(); if (from < 0) from = 0; if (from < _filterResults.size()) { - int32 to = (yTo / int32(st::dialogsRowHeight)) + 1, w = width(); + int32 to = (yTo / int32(DialogsRowHeight())) + 1, w = width(); if (to > _filterResults.size()) to = _filterResults.size(); for (; from < to; ++from) { @@ -2491,20 +2499,20 @@ void InnerWidget::loadPeerPhotos() { } } - from = (yFrom > filteredOffset() + st::searchedBarHeight ? ((yFrom - filteredOffset() - st::searchedBarHeight) / int32(st::dialogsRowHeight)) : 0) - _filterResults.size(); + from = (yFrom > filteredOffset() + st::searchedBarHeight ? ((yFrom - filteredOffset() - st::searchedBarHeight) / int32(DialogsRowHeight())) : 0) - _filterResults.size(); if (from < 0) from = 0; if (from < _peerSearchResults.size()) { - int32 to = (yTo > filteredOffset() + st::searchedBarHeight ? ((yTo - filteredOffset() - st::searchedBarHeight) / int32(st::dialogsRowHeight)) : 0) - _filterResults.size() + 1, w = width(); + int32 to = (yTo > filteredOffset() + st::searchedBarHeight ? ((yTo - filteredOffset() - st::searchedBarHeight) / int32(DialogsRowHeight())) : 0) - _filterResults.size() + 1, w = width(); if (to > _peerSearchResults.size()) to = _peerSearchResults.size(); for (; from < to; ++from) { _peerSearchResults[from]->peer->loadUserpic(); } } - from = (yFrom > filteredOffset() + ((_peerSearchResults.empty() ? 0 : st::searchedBarHeight) + st::searchedBarHeight) ? ((yFrom - filteredOffset() - (_peerSearchResults.empty() ? 0 : st::searchedBarHeight) - st::searchedBarHeight) / int32(st::dialogsRowHeight)) : 0) - _filterResults.size() - _peerSearchResults.size(); + from = (yFrom > filteredOffset() + ((_peerSearchResults.empty() ? 0 : st::searchedBarHeight) + st::searchedBarHeight) ? ((yFrom - filteredOffset() - (_peerSearchResults.empty() ? 0 : st::searchedBarHeight) - st::searchedBarHeight) / int32(DialogsRowHeight())) : 0) - _filterResults.size() - _peerSearchResults.size(); if (from < 0) from = 0; if (from < _searchResults.size()) { - int32 to = (yTo > filteredOffset() + (_peerSearchResults.empty() ? 0 : st::searchedBarHeight) + st::searchedBarHeight ? ((yTo - filteredOffset() - (_peerSearchResults.empty() ? 0 : st::searchedBarHeight) - st::searchedBarHeight) / int32(st::dialogsRowHeight)) : 0) - _filterResults.size() - _peerSearchResults.size() + 1, w = width(); + int32 to = (yTo > filteredOffset() + (_peerSearchResults.empty() ? 0 : st::searchedBarHeight) + st::searchedBarHeight ? ((yTo - filteredOffset() - (_peerSearchResults.empty() ? 0 : st::searchedBarHeight) - st::searchedBarHeight) / int32(DialogsRowHeight())) : 0) - _filterResults.size() - _peerSearchResults.size() + 1, w = width(); if (to > _searchResults.size()) to = _searchResults.size(); for (; from < to; ++from) { @@ -2860,7 +2868,7 @@ void InnerWidget::userOnlineUpdated(const Notify::PeerUpdate &update) { const auto size = st::dialogsOnlineBadgeSize; const auto stroke = st::dialogsOnlineBadgeStroke; const auto skip = st::dialogsOnlineBadgeSkip; - const auto edge = st::dialogsPadding.x() + st::dialogsPhotoSize; + const auto edge = st::dialogsPadding.x() + DialogsPhotoSize(); const auto updateRect = QRect( edge - skip.x() - size, edge - skip.y() - size, @@ -2893,11 +2901,11 @@ void InnerWidget::userOnlineUpdated(const Notify::PeerUpdate &update) { [](not_null row) { return row->history(); }); const auto index = (i - begin(_filterResults)); const auto row = (i == end(_filterResults)) ? nullptr : i->get(); - return { row, filteredOffset() + index * st::dialogsRowHeight }; + return { row, filteredOffset() + index * DialogsRowHeight() }; }; if (const auto &[row, top] = findRow(history); row != nullptr) { const auto visible = (top < _visibleBottom) - && (top + st::dialogsRowHeight > _visibleTop); + && (top + DialogsRowHeight() > _visibleTop); row->setOnline( Data::OnlineTextActive(user, base::unixtime::now()), visible ? Fn(crl::guard(this, repaint)) : nullptr); diff --git a/Telegram/SourceFiles/dialogs/dialogs_layout.cpp b/Telegram/SourceFiles/dialogs/dialogs_layout.cpp index 00fb2558a..16133ce35 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_layout.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_layout.cpp @@ -77,15 +77,18 @@ void PaintNarrowCounter( int unreadCount, bool active, bool unreadMuted, - bool mentionMuted) { + bool mentionMuted, + int lines = 2) { auto skipBeforeMention = 0; if (displayUnreadCounter || displayUnreadMark) { auto counter = (unreadCount > 0) ? QString::number(unreadCount) : QString(); const auto allowDigits = displayMentionBadge ? 1 : 3; - auto unreadRight = st::dialogsPadding.x() + st::dialogsPhotoSize; - auto unreadTop = st::dialogsPadding.y() + st::dialogsPhotoSize - st::dialogsUnreadHeight; + auto unreadRight = st::dialogsPadding.x() + (cDialogListLines() == 1 ? st::dialogsUnreadHeight : st::dialogsPhotoSize); + auto unreadTop = (lines == 1 + ? st::dialogsPadding.y() + : st::dialogsPadding.y() + st::dialogsPhotoSize - st::dialogsUnreadHeight); auto unreadWidth = 0; UnreadBadgeStyle st; @@ -96,8 +99,10 @@ void PaintNarrowCounter( } if (displayMentionBadge) { auto counter = qsl("@"); - auto unreadRight = st::dialogsPadding.x() + st::dialogsPhotoSize - skipBeforeMention; - auto unreadTop = st::dialogsPadding.y() + st::dialogsPhotoSize - st::dialogsUnreadHeight; + auto unreadRight = st::dialogsPadding.x() + (cDialogListLines() == 1 ? st::dialogsUnreadHeight : st::dialogsPhotoSize) - skipBeforeMention; + auto unreadTop = (lines == 1 + ? st::dialogsPadding.y() + : st::dialogsPadding.y() + st::dialogsPhotoSize - st::dialogsUnreadHeight); auto unreadWidth = 0; UnreadBadgeStyle st; @@ -212,6 +217,173 @@ enum class Flag { }; inline constexpr bool is_flag_type(Flag) { return true; } +template +void paintOneLineRow( + Painter &p, + not_null row, + not_null entry, + Dialogs::Key chat, + PeerData *from, + const HiddenSenderInfo *hiddenSenderInfo, + HistoryItem *item, + const Data::Draft *draft, + QDateTime date, + int fullWidth, + base::flags flags, + crl::time ms, + PaintItemCallback &&paintItemCallback, + PaintCounterCallback &&paintCounterCallback) { + const auto supportMode = Auth().supportMode(); + if (supportMode) { + draft = nullptr; + } + + auto active = (flags & Flag::Active); + auto selected = (flags & Flag::Selected); + auto fullRect = QRect(0, 0, fullWidth, st::dialogsImportantBarHeight); + auto bg = active + ? st::dialogsBgActive + : (selected + ? st::dialogsBgOver + : st::dialogsBg); + auto ripple = active + ? st::dialogsRippleBgActive + : st::dialogsRippleBg; + p.fillRect(fullRect, bg); + row->paintRipple(p, 0, 0, fullWidth, &ripple->c); + + if (flags & Flag::SavedMessages) { + Ui::EmptyUserpic::PaintSavedMessages( + p, + st::dialogsPadding.x(), + st::dialogsPadding.y(), + fullWidth, + st::dialogsUnreadHeight); + } else if (from) { + row->paintUserpic( + p, + from, + (flags & Flag::AllowUserOnline), + active, + fullWidth); + } else if (hiddenSenderInfo) { + hiddenSenderInfo->userpic.paint( + p, + st::dialogsPadding.x(), + st::dialogsPadding.y(), + fullWidth, + st::dialogsUnreadHeight); + } else { + entry->paintUserpicLeft( + p, + st::dialogsPadding.x(), + st::dialogsPadding.y(), + fullWidth, + st::dialogsUnreadHeight); + } + + auto nameleft = st::dialogsPadding.x() * 2 + st::dialogsUnreadHeight; + if (fullWidth <= nameleft) { + if (!draft && item && !item->isEmpty()) { + paintCounterCallback(); + } + return; + } + + const auto history = chat.history(); + auto namewidth = fullWidth - nameleft - st::dialogsPadding.x(); + auto rectForName = QRect( + nameleft, + st::dialogsPadding.y(), + namewidth, + st::dialogsTextFont->height); + + const auto promoted = (history && history->useProxyPromotion()) + && !(flags & (Flag::SearchResult/* | Flag::FeedSearchResult*/)); // #feed + if (promoted) { + const auto text = tr::lng_proxy_sponsor(tr::now); + PaintRowTopRight(p, text, rectForName, active, selected); + } else if (from && !(flags & Flag::SearchResult/* | Flag::FeedSearchResult*/)) { // #feed + if (const auto chatTypeIcon = ChatTypeIcon(from, active, selected)) { + chatTypeIcon->paint(p, rectForName.topLeft(), fullWidth); + rectForName.setLeft(rectForName.left() + st::dialogsChatTypeSkip); + } + //} else if (const auto feed = chat.feed()) { // #feed + // if (const auto feedTypeIcon = FeedTypeIcon(feed, active, selected)) { + // feedTypeIcon->paint(p, rectForName.topLeft(), fullWidth); + // rectForName.setLeft(rectForName.left() + st::dialogsChatTypeSkip); + // } + } + if (!draft + && !(supportMode + && Auth().supportHelper().isOccupiedBySomeone(history)) + && item + && !item->isEmpty()) { + const auto nameWithoutCounterWidth = paintItemCallback(nameleft, (flags & Flag::SearchResult ? namewidth : rectForName.width())); + rectForName.setWidth(nameWithoutCounterWidth - st::dialogsPadding.x()); + } else if (entry->isPinnedDialog() && !entry->fixedOnTopIndex()) { + auto &icon = (active ? st::dialogsPinnedIconActive : (selected ? st::dialogsPinnedIconOver : st::dialogsPinnedIcon)); + icon.paint(p, fullWidth - st::dialogsPadding.x() - icon.width(), st::dialogsPadding.y(), fullWidth); + rectForName.setWidth(rectForName.width() - icon.width() - st::dialogsUnreadPadding); + } + + QString text; + + if (flags & Flag::SavedMessages) { + text = tr::lng_saved_messages(tr::now); + p.setPen(active + ? st::dialogsNameFgActive + : selected + ? st::dialogsNameFgOver + : st::dialogsNameFg); + } else if (from) { + if (!(flags & Flag::SearchResult)) { + const auto badgeStyle = Ui::PeerBadgeStyle{ + (active + ? &st::dialogsVerifiedIconActive + : selected + ? &st::dialogsVerifiedIconOver + : &st::dialogsVerifiedIcon), + (active + ? &st::dialogsScamFgActive + : selected + ? &st::dialogsScamFgOver + : &st::dialogsScamFg) }; + const auto badgeWidth = Ui::DrawPeerBadgeGetWidth( + from, + p, + rectForName, + from->nameText().maxWidth(), + fullWidth, + badgeStyle); + rectForName.setWidth(rectForName.width() - badgeWidth); + + text = from->nameText().toString(); + p.setPen(active + ? st::dialogsNameFgActive + : selected + ? st::dialogsNameFgOver + : st::dialogsNameFg); + p.setFont(st::dialogsTextFont); + } + } else if (hiddenSenderInfo) { + text = hiddenSenderInfo->nameText.toString(); + } else { + text = entry->chatListName(); + const auto nameFg = active + ? st::dialogsNameFgActive + : (selected + ? st::dialogsArchiveFgOver + : st::dialogsArchiveFg); + p.setPen(nameFg); + } + + if (!(from && (flags & Flag::SearchResult))) { + Ui::Text::String textStr = { st::dialogsTextStyle, text }; + textStr.drawElided(p, rectForName.left(), rectForName.top(), rectForName.width()); + } +} + template void paintRow( Painter &p, @@ -659,6 +831,10 @@ void RowPainter::paint( ? history->hasUnreadMentions() : false; const auto displayUnreadCounter = [&] { + if (fullWidth < st::columnMinimalWidthLeft && cDialogListLines() == 1) { + return false; + } + if (displayMentionBadge && unreadCount == 1 && item @@ -689,9 +865,12 @@ void RowPainter::paint( | (allowUserOnline ? Flag::AllowUserOnline : Flag(0)) | (peer && peer->isSelf() ? Flag::SavedMessages : Flag(0)); const auto paintItemCallback = [&](int nameleft, int namewidth) { - const auto texttop = st::dialogsPadding.y() - + st::msgNameFont->height - + st::dialogsSkip; + const auto texttop = (cDialogListLines() == 1 + ? st::dialogsPadding.y() + : st::dialogsPadding.y() + + st::msgNameFont->height + + st::dialogsSkip); + const auto availableWidth = PaintWideCounter( p, texttop, @@ -706,36 +885,40 @@ void RowPainter::paint( selected, unreadMuted, mentionMuted); - const auto &color = active - ? st::dialogsTextFgServiceActive - : (selected - ? st::dialogsTextFgServiceOver - : st::dialogsTextFgService); - const auto itemRect = QRect( - nameleft, - texttop, - availableWidth, - st::dialogsTextFont->height); - const auto actionWasPainted = history ? history->paintSendAction( - p, - itemRect.x(), - itemRect.y(), - itemRect.width(), - fullWidth, - color, - ms) : false; - if (const auto folder = row->folder()) { - PaintListEntryText(p, itemRect, active, selected, row); - } else if (!actionWasPainted) { - item->drawInDialog( + if (cDialogListLines() > 1 || flags & Flag::SearchResult) { + const auto &color = active + ? st::dialogsTextFgServiceActive + : (selected + ? st::dialogsTextFgServiceOver + : st::dialogsTextFgService); + const auto itemRect = QRect( + nameleft, + texttop, + availableWidth, + st::dialogsTextFont->height); + const auto actionWasPainted = history ? history->paintSendAction( p, - itemRect, - active, - selected, - HistoryItem::DrawInDialog::Normal, - entry->textCachedFor, - entry->lastItemTextCache); + itemRect.x(), + itemRect.y(), + itemRect.width(), + fullWidth, + color, + ms) : false; + if (const auto folder = row->folder()) { + PaintListEntryText(p, itemRect, active, selected, row); + } else if (!actionWasPainted) { + item->drawInDialog( + p, + itemRect, + active, + selected, + HistoryItem::DrawInDialog::Normal, + entry->textCachedFor, + entry->lastItemTextCache); + } } + + return availableWidth; }; const auto paintCounterCallback = [&] { PaintNarrowCounter( @@ -746,23 +929,42 @@ void RowPainter::paint( unreadCount, active, unreadMuted, - mentionMuted); + mentionMuted, + cDialogListLines()); }; - paintRow( - p, - row, - entry, - row->key(), - from, - nullptr, - item, - cloudDraft, - displayDate, - fullWidth, - flags, - ms, - paintItemCallback, - paintCounterCallback); + if (cDialogListLines() == 1) { + paintOneLineRow( + p, + row, + entry, + row->key(), + from, + nullptr, + item, + cloudDraft, + displayDate, + fullWidth, + flags, + ms, + paintItemCallback, + paintCounterCallback); + } else { + paintRow( + p, + row, + entry, + row->key(), + from, + nullptr, + item, + cloudDraft, + displayDate, + fullWidth, + flags, + ms, + paintItemCallback, + paintCounterCallback); + } } void RowPainter::paint( @@ -819,11 +1021,19 @@ void RowPainter::paint( && !displayMentionBadge && unreadMark; const auto displayPinnedIcon = false; - + const auto showSavedMessages = history->peer->isSelf() + && !row->searchInChat(); + const auto flags = (active ? Flag::Active : Flag(0)) + | (selected ? Flag::Selected : Flag(0)) + | Flag::SearchResult + | (showSavedMessages ? Flag::SavedMessages : Flag(0))/* // #feed + | (row->searchInChat().feed() ? Flag::FeedSearchResult : Flag(0))*/; const auto paintItemCallback = [&](int nameleft, int namewidth) { - const auto texttop = st::dialogsPadding.y() - + st::msgNameFont->height - + st::dialogsSkip; + const auto texttop = (cDialogListLines() == 1 + ? st::dialogsPadding.y() + : st::dialogsPadding.y() + + st::msgNameFont->height + + st::dialogsSkip); const auto availableWidth = PaintWideCounter( p, texttop, @@ -839,19 +1049,23 @@ void RowPainter::paint( unreadMuted, mentionMuted); - const auto itemRect = QRect( - nameleft, - texttop, - availableWidth, - st::dialogsTextFont->height); - item->drawInDialog( - p, - itemRect, - active, - selected, - drawInDialogWay, - row->_cacheFor, - row->_cache); + if (cDialogListLines() > 1 || flags & Flag::SearchResult) { + const auto itemRect = QRect( + nameleft, + texttop, + availableWidth, + st::dialogsTextFont->height); + item->drawInDialog( + p, + itemRect, + active, + selected, + drawInDialogWay, + row->_cacheFor, + row->_cache); + } + + return availableWidth; }; const auto paintCounterCallback = [&] { PaintNarrowCounter( @@ -862,34 +1076,46 @@ void RowPainter::paint( unreadCount, active, unreadMuted, - mentionMuted); + mentionMuted, + cDialogListLines()); }; - const auto showSavedMessages = history->peer->isSelf() - && !row->searchInChat(); - const auto flags = (active ? Flag::Active : Flag(0)) - | (selected ? Flag::Selected : Flag(0)) - | Flag::SearchResult - | (showSavedMessages ? Flag::SavedMessages : Flag(0))/* // #feed - | (row->searchInChat().feed() ? Flag::FeedSearchResult : Flag(0))*/; - paintRow( - p, - row, - history, - history, - from, - hiddenSenderInfo, - item, - cloudDraft, - ItemDateTime(item), - fullWidth, - flags, - ms, - paintItemCallback, - paintCounterCallback); + if (cDialogListLines() == 1) { + paintOneLineRow( + p, + row, + history, + history, + from, + hiddenSenderInfo, + item, + cloudDraft, + ItemDateTime(item), + fullWidth, + flags, + ms, + paintItemCallback, + paintCounterCallback); + } else { + paintRow( + p, + row, + history, + history, + from, + hiddenSenderInfo, + item, + cloudDraft, + ItemDateTime(item), + fullWidth, + flags, + ms, + paintItemCallback, + paintCounterCallback); + } } QRect RowPainter::sendActionAnimationRect(int animationWidth, int animationHeight, int fullWidth, bool textUpdated) { - auto nameleft = st::dialogsPadding.x() + st::dialogsPhotoSize + st::dialogsPhotoPadding; + auto nameleft = st::dialogsPadding.x() + (cDialogListLines() == 1 ? st::dialogsUnreadHeight : st::dialogsPhotoSize) + st::dialogsPhotoPadding; auto namewidth = fullWidth - nameleft - st::dialogsPadding.x(); auto texttop = st::dialogsPadding.y() + st::msgNameFont->height + st::dialogsSkip; return QRect(nameleft, texttop, textUpdated ? namewidth : animationWidth, animationHeight); diff --git a/Telegram/SourceFiles/dialogs/dialogs_row.cpp b/Telegram/SourceFiles/dialogs/dialogs_row.cpp index 7ce16d30f..c25fcc67d 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_row.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_row.cpp @@ -146,7 +146,7 @@ void BasicRow::PaintOnlineFrame( q, 0, 0, - st::dialogsPhotoSize); + (cDialogListLines() == 1 ? st::dialogsUnreadHeight : st::dialogsPhotoSize)); PainterHighQualityEnabler hq(q); q.setCompositionMode(QPainter::CompositionMode_Source); @@ -154,7 +154,7 @@ void BasicRow::PaintOnlineFrame( const auto size = st::dialogsOnlineBadgeSize; const auto stroke = st::dialogsOnlineBadgeStroke; const auto skip = st::dialogsOnlineBadgeSkip; - const auto edge = st::dialogsPadding.x() + st::dialogsPhotoSize; + const auto edge = st::dialogsPadding.x() + (cDialogListLines() == 1 ? st::dialogsUnreadHeight : st::dialogsPhotoSize); const auto shrink = (size / 2) * (1. - data->online); auto pen = QPen(Qt::transparent); @@ -182,13 +182,13 @@ void BasicRow::paintUserpic( const auto online = _onlineUserpic ? _onlineUserpic->animation.value(_online ? 1. : 0.) : (_online ? 1. : 0.); - if (!allowOnline || online == 0.) { + if (!allowOnline || cDialogListLines() == 1 || online == 0.) { peer->paintUserpicLeft( p, st::dialogsPadding.x(), st::dialogsPadding.y(), fullWidth, - st::dialogsPhotoSize); + (cDialogListLines() == 1 ? st::dialogsUnreadHeight : st::dialogsPhotoSize)); if (!allowOnline || !_online) { _onlineUserpic = nullptr; } @@ -197,8 +197,8 @@ void BasicRow::paintUserpic( ensureOnlineUserpic(); if (_onlineUserpic->frame.isNull()) { _onlineUserpic->frame = QImage( - st::dialogsPhotoSize * cRetinaFactor(), - st::dialogsPhotoSize * cRetinaFactor(), + (cDialogListLines() == 1 ? st::dialogsUnreadHeight : st::dialogsPhotoSize) * cRetinaFactor(), + (cDialogListLines() == 1 ? st::dialogsUnreadHeight : st::dialogsPhotoSize) * cRetinaFactor(), QImage::Format_ARGB32_Premultiplied); _onlineUserpic->frame.setDevicePixelRatio(cRetinaFactor()); } diff --git a/Telegram/SourceFiles/dialogs/dialogs_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_widget.cpp index 5c8952e24..f91996961 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_widget.cpp @@ -1446,7 +1446,7 @@ void Widget::updateControlsGeometry() { _forwardCancel->moveToLeft(0, filterAreaTop); filterAreaTop += st::dialogsForwardHeight; } - auto smallLayoutWidth = (st::dialogsPadding.x() + st::dialogsPhotoSize + st::dialogsPadding.x()); + auto smallLayoutWidth = (st::dialogsPadding.x() + (cDialogListLines() == 1 ? st::dialogsUnreadHeight : st::dialogsPhotoSize) + st::dialogsPadding.x()); auto smallLayoutRatio = (width() < st::columnMinimalWidthLeft) ? (st::columnMinimalWidthLeft - width()) / float64(st::columnMinimalWidthLeft - smallLayoutWidth) : 0.; auto filterLeft = st::dialogsFilterPadding.x() + _mainMenuToggle->width() + st::dialogsFilterPadding.x(); auto filterRight = (Global::LocalPasscode() ? (st::dialogsFilterPadding.x() + _lockUnlock->width()) : st::dialogsFilterSkip) + st::dialogsFilterPadding.x(); @@ -1668,7 +1668,7 @@ void Widget::onCancelSearchInChat() { void Widget::onDialogMoved(int movedFrom, int movedTo) { int32 st = _scroll->scrollTop(); if (st > movedTo && st < movedFrom) { - _scroll->scrollToY(st + st::dialogsRowHeight); + _scroll->scrollToY(st + (cDialogListLines() == 1 ? st::dialogsImportantBarHeight : st::dialogsRowHeight)); } } diff --git a/Telegram/SourceFiles/settings.cpp b/Telegram/SourceFiles/settings.cpp index 97e66dcb9..666671020 100644 --- a/Telegram/SourceFiles/settings.cpp +++ b/Telegram/SourceFiles/settings.cpp @@ -261,4 +261,6 @@ bool AddCustomScale(int scale) { void ClearCustomScales() { gInterfaceScales.clear(); -} \ No newline at end of file +} + +int gDialogListLines = 2; \ No newline at end of file diff --git a/Telegram/SourceFiles/settings.h b/Telegram/SourceFiles/settings.h index 4dbc67ade..4d6466a57 100644 --- a/Telegram/SourceFiles/settings.h +++ b/Telegram/SourceFiles/settings.h @@ -225,4 +225,5 @@ using ScaleVector = std::vector; DeclareRefSetting(ScaleVector, InterfaceScales); bool HasCustomScales(); bool AddCustomScale(int scale); -void ClearCustomScales(); \ No newline at end of file +void ClearCustomScales(); +DeclareSetting(int, DialogListLines); diff --git a/Telegram/SourceFiles/window/window_peer_menu.cpp b/Telegram/SourceFiles/window/window_peer_menu.cpp index d0478f351..6c62b05db 100644 --- a/Telegram/SourceFiles/window/window_peer_menu.cpp +++ b/Telegram/SourceFiles/window/window_peer_menu.cpp @@ -620,14 +620,16 @@ void FolderFiller::addTogglesForArchive() { return; } const auto controller = _controller; - const auto hidden = controller->session().settings().archiveCollapsed(); - const auto text = hidden - ? tr::lng_context_archive_expand(tr::now) - : tr::lng_context_archive_collapse(tr::now); - _addAction(text, [=] { - controller->session().settings().setArchiveCollapsed(!hidden); - controller->session().saveSettingsDelayed(); - }); + if (cDialogListLines() != 1) { + const auto hidden = (controller->session().settings().archiveCollapsed()); + const auto text = hidden + ? tr::lng_context_archive_expand(tr::now) + : tr::lng_context_archive_collapse(tr::now); + _addAction(text, [=] { + controller->session().settings().setArchiveCollapsed(!hidden); + controller->session().saveSettingsDelayed(); + }); + } _addAction(tr::lng_context_archive_to_menu(tr::now), [=] { auto toast = Ui::Toast::Config(); diff --git a/Telegram/SourceFiles/window/window_session_controller.cpp b/Telegram/SourceFiles/window/window_session_controller.cpp index 34ee9a7ad..8627fd2c6 100644 --- a/Telegram/SourceFiles/window/window_session_controller.cpp +++ b/Telegram/SourceFiles/window/window_session_controller.cpp @@ -309,7 +309,7 @@ bool SessionController::isGifPausedAtLeastFor(GifPauseReason reason) const { } int SessionController::dialogsSmallColumnWidth() const { - return st::dialogsPadding.x() + st::dialogsPhotoSize + st::dialogsPadding.x(); + return st::dialogsPadding.x() + (cDialogListLines() == 1 ? st::dialogsUnreadHeight : st::dialogsPhotoSize) + st::dialogsPadding.x(); } int SessionController::minimalThreeColumnWidth() const {