Compact mode in chat list

This commit is contained in:
Eric Kotato 2019-10-24 03:38:11 +03:00
parent 4606e5d5bb
commit bc53b60118
9 changed files with 450 additions and 201 deletions

View file

@ -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; return true;
} }
@ -246,6 +254,7 @@ void Manager::writeDefaultFile() {
settings.insert(qsl("show_chat_id"), cShowChatId()); settings.insert(qsl("show_chat_id"), cShowChatId());
settings.insert(qsl("net_speed_boost"), QJsonValue(QJsonValue::Null)); settings.insert(qsl("net_speed_boost"), QJsonValue(QJsonValue::Null));
settings.insert(qsl("show_phone_in_drawer"), cShowPhoneInDrawer()); settings.insert(qsl("show_phone_in_drawer"), cShowPhoneInDrawer());
settings.insert(qsl("chat_list_lines"), cDialogListLines());
auto settingsScales = QJsonArray(); auto settingsScales = QJsonArray();
settings.insert(qsl("scales"), settingsScales); settings.insert(qsl("scales"), settingsScales);
@ -298,6 +307,7 @@ void Manager::writeCurrentSettings() {
settings.insert(qsl("show_chat_id"), cShowChatId()); settings.insert(qsl("show_chat_id"), cShowChatId());
settings.insert(qsl("net_speed_boost"), cNetSpeedBoost()); settings.insert(qsl("net_speed_boost"), cNetSpeedBoost());
settings.insert(qsl("show_phone_in_drawer"), cShowPhoneInDrawer()); settings.insert(qsl("show_phone_in_drawer"), cShowPhoneInDrawer());
settings.insert(qsl("chat_list_lines"), cDialogListLines());
auto settingsScales = QJsonArray(); auto settingsScales = QJsonArray();
auto currentScales = cInterfaceScales(); auto currentScales = cInterfaceScales();

View file

@ -53,6 +53,14 @@ namespace {
constexpr auto kHashtagResultsLimit = 5; constexpr auto kHashtagResultsLimit = 5;
constexpr auto kStartReorderThreshold = 30; 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<Dialogs::IndexedList*> list) { int FixedOnTopDialogsCount(not_null<Dialogs::IndexedList*> list) {
auto result = 0; auto result = 0;
for (const auto row : *list) { for (const auto row : *list) {
@ -287,7 +295,7 @@ void InnerWidget::refreshWithCollapsedRows(bool toTop) {
? (*list->begin())->folder() ? (*list->begin())->folder()
: nullptr; : nullptr;
const auto inMainMenu = session().settings().archiveInMainMenu(); 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) { if (_selected && _selected->folder() == archive) {
_selected = nullptr; _selected = nullptr;
} }
@ -315,7 +323,7 @@ void InnerWidget::refreshWithCollapsedRows(bool toTop) {
int InnerWidget::dialogsOffset() const { int InnerWidget::dialogsOffset() const {
return _collapsedRows.size() * st::dialogsImportantBarHeight return _collapsedRows.size() * st::dialogsImportantBarHeight
- _skipTopDialogs * st::dialogsRowHeight; - _skipTopDialogs * DialogsRowHeight();
} }
int InnerWidget::fixedOnTopCount() const { int InnerWidget::fixedOnTopCount() const {
@ -331,7 +339,7 @@ int InnerWidget::fixedOnTopCount() const {
} }
int InnerWidget::pinnedOffset() const { int InnerWidget::pinnedOffset() const {
return dialogsOffset() + fixedOnTopCount() * st::dialogsRowHeight; return dialogsOffset() + fixedOnTopCount() * DialogsRowHeight();
} }
int InnerWidget::filteredOffset() const { int InnerWidget::filteredOffset() const {
@ -339,11 +347,11 @@ int InnerWidget::filteredOffset() const {
} }
int InnerWidget::peerSearchOffset() const { int InnerWidget::peerSearchOffset() const {
return filteredOffset() + (_filterResults.size() * st::dialogsRowHeight) + st::searchedBarHeight; return filteredOffset() + (_filterResults.size() * DialogsRowHeight()) + st::searchedBarHeight;
} }
int InnerWidget::searchedOffset() const { 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) { if (_searchInChat) {
result += searchInChatSkip(); result += searchInChatSkip();
} }
@ -394,7 +402,7 @@ void InnerWidget::paintEvent(QPaintEvent *e) {
const auto rows = shownDialogs(); const auto rows = shownDialogs();
const auto &list = rows->all(); 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 active = activeEntry.key;
const auto selected = _menuRow.key const auto selected = _menuRow.key
? _menuRow.key ? _menuRow.key
@ -409,7 +417,7 @@ void InnerWidget::paintEvent(QPaintEvent *e) {
const auto skip = dialogsOffset(); const auto skip = dialogsOffset();
auto reorderingPinned = (_aboveIndex >= 0 && !_pinnedRows.empty()); auto reorderingPinned = (_aboveIndex >= 0 && !_pinnedRows.empty());
if (reorderingPinned) { if (reorderingPinned) {
dialogsClip = dialogsClip.marginsAdded(QMargins(0, st::dialogsRowHeight, 0, st::dialogsRowHeight)); dialogsClip = dialogsClip.marginsAdded(QMargins(0, DialogsRowHeight(), 0, DialogsRowHeight()));
} }
const auto promoted = fixedOnTopCount(); 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) { while (i != list.cend() && (*i)->pos() < _skipTopDialogs) {
++i; ++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 we're reordering pinned chats we need to fill this area background first.
if (reorderingPinned) { 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) { for (auto e = list.cend(); i != e; ++i) {
auto row = (*i); auto row = (*i);
if ((lastPaintedPos - _skipTopDialogs) * st::dialogsRowHeight >= dialogsClip.top() - skip + dialogsClip.height()) { if ((lastPaintedPos - _skipTopDialogs) * DialogsRowHeight() >= dialogsClip.top() - skip + dialogsClip.height()) {
break; break;
} }
@ -462,7 +470,7 @@ void InnerWidget::paintEvent(QPaintEvent *e) {
paintDialog(row); paintDialog(row);
} }
p.translate(0, st::dialogsRowHeight); p.translate(0, DialogsRowHeight());
++lastPaintedPos; ++lastPaintedPos;
} }
@ -471,9 +479,9 @@ void InnerWidget::paintEvent(QPaintEvent *e) {
auto i = list.cfind(promoted + _aboveIndex, 1); auto i = list.cfind(promoted + _aboveIndex, 1);
auto pos = (i == list.cend()) ? -1 : (*i)->pos(); auto pos = (i == list.cend()) ? -1 : (*i)->pos();
if (pos == promoted + _aboveIndex) { if (pos == promoted + _aboveIndex) {
p.translate(0, (pos - lastPaintedPos) * st::dialogsRowHeight); p.translate(0, (pos - lastPaintedPos) * DialogsRowHeight());
paintDialog(*i); 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()) { if (!_filterResults.empty()) {
auto skip = filteredOffset(); auto skip = filteredOffset();
auto from = floorclamp(r.y() - skip, st::dialogsRowHeight, 0, _filterResults.size()); auto from = floorclamp(r.y() - skip, DialogsRowHeight(), 0, _filterResults.size());
auto to = ceilclamp(r.y() + r.height() - skip, st::dialogsRowHeight, 0, _filterResults.size()); auto to = ceilclamp(r.y() + r.height() - skip, DialogsRowHeight(), 0, _filterResults.size());
p.translate(0, from * st::dialogsRowHeight); p.translate(0, from * DialogsRowHeight());
if (from < _filterResults.size()) { if (from < _filterResults.size()) {
for (; from < to; ++from) { for (; from < to; ++from) {
const auto row = _filterResults[from]; const auto row = _filterResults[from];
@ -557,7 +565,7 @@ void InnerWidget::paintEvent(QPaintEvent *e) {
active, active,
selected, selected,
ms); ms);
p.translate(0, st::dialogsRowHeight); p.translate(0, DialogsRowHeight());
} }
} }
} }
@ -570,9 +578,9 @@ void InnerWidget::paintEvent(QPaintEvent *e) {
p.translate(0, st::searchedBarHeight); p.translate(0, st::searchedBarHeight);
auto skip = peerSearchOffset(); auto skip = peerSearchOffset();
auto from = floorclamp(r.y() - skip, st::dialogsRowHeight, 0, _peerSearchResults.size()); auto from = floorclamp(r.y() - skip, DialogsRowHeight(), 0, _peerSearchResults.size());
auto to = ceilclamp(r.y() + r.height() - skip, st::dialogsRowHeight, 0, _peerSearchResults.size()); auto to = ceilclamp(r.y() + r.height() - skip, DialogsRowHeight(), 0, _peerSearchResults.size());
p.translate(0, from * st::dialogsRowHeight); p.translate(0, from * DialogsRowHeight());
if (from < _peerSearchResults.size()) { if (from < _peerSearchResults.size()) {
const auto activePeer = activeEntry.key.peer(); const auto activePeer = activeEntry.key.peer();
for (; from < to; ++from) { for (; from < to; ++from) {
@ -586,7 +594,7 @@ void InnerWidget::paintEvent(QPaintEvent *e) {
? _peerSearchPressed ? _peerSearchPressed
: _peerSearchSelected)); : _peerSearchSelected));
paintPeerSearchResult(p, result.get(), fullWidth, active, selected); 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); p.translate(0, st::searchedBarHeight);
auto skip = searchedOffset(); auto skip = searchedOffset();
auto from = floorclamp(r.y() - skip, st::dialogsRowHeight, 0, _searchResults.size()); auto from = floorclamp(r.y() - skip, DialogsRowHeight(), 0, _searchResults.size());
auto to = ceilclamp(r.y() + r.height() - skip, st::dialogsRowHeight, 0, _searchResults.size()); auto to = ceilclamp(r.y() + r.height() - skip, DialogsRowHeight(), 0, _searchResults.size());
p.translate(0, from * st::dialogsRowHeight); p.translate(0, from * DialogsRowHeight());
if (from < _searchResults.size()) { if (from < _searchResults.size()) {
for (; from < to; ++from) { for (; from < to; ++from) {
const auto &result = _searchResults[from]; const auto &result = _searchResults[from];
@ -649,7 +657,7 @@ void InnerWidget::paintEvent(QPaintEvent *e) {
selected, selected,
ms, ms,
showUnreadInSearchResults); showUnreadInSearchResults);
p.translate(0, st::dialogsRowHeight); p.translate(0, DialogsRowHeight());
} }
} }
} }
@ -721,7 +729,7 @@ void InnerWidget::paintPeerSearchResult(
int fullWidth, int fullWidth,
bool active, bool active,
bool selected) const { 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)); p.fillRect(fullRect, active ? st::dialogsBgActive : (selected ? st::dialogsBgOver : st::dialogsBg));
if (!active) { if (!active) {
result->row.paintRipple(p, 0, 0, fullWidth); result->row.paintRipple(p, 0, 0, fullWidth);
@ -729,9 +737,9 @@ void InnerWidget::paintPeerSearchResult(
auto peer = result->peer; auto peer = result->peer;
auto userpicPeer = (peer->migrateTo() ? peer->migrateTo() : 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(); auto namewidth = fullWidth - nameleft - st::dialogsPadding.x();
QRect rectForName(nameleft, st::dialogsPadding.y() + st::dialogsNameTop, namewidth, st::msgNameFont->height); QRect rectForName(nameleft, st::dialogsPadding.y() + st::dialogsNameTop, namewidth, st::msgNameFont->height);
@ -946,7 +954,7 @@ void InnerWidget::selectByMouse(QPoint globalPosition) {
: (mouseY >= offset) : (mouseY >= offset)
? shownDialogs()->rowAtY( ? shownDialogs()->rowAtY(
mouseY - offset, mouseY - offset,
st::dialogsRowHeight) DialogsRowHeight())
: nullptr; : nullptr;
if (_selected != selected || _collapsedSelected != collapsedSelected) { if (_selected != selected || _collapsedSelected != collapsedSelected) {
updateSelectedRow(); updateSelectedRow();
@ -977,7 +985,7 @@ void InnerWidget::selectByMouse(QPoint globalPosition) {
} }
if (!_filterResults.empty()) { if (!_filterResults.empty()) {
auto skip = filteredOffset(); 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()) { if (filteredSelected < 0 || filteredSelected >= _filterResults.size()) {
filteredSelected = -1; filteredSelected = -1;
} }
@ -989,7 +997,7 @@ void InnerWidget::selectByMouse(QPoint globalPosition) {
} }
if (!_peerSearchResults.empty()) { if (!_peerSearchResults.empty()) {
auto skip = peerSearchOffset(); 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()) { if (peerSearchSelected < 0 || peerSearchSelected >= _peerSearchResults.size()) {
peerSearchSelected = -1; peerSearchSelected = -1;
} }
@ -1001,7 +1009,7 @@ void InnerWidget::selectByMouse(QPoint globalPosition) {
} }
if (!_waitingForSearch && !_searchResults.empty()) { if (!_waitingForSearch && !_searchResults.empty()) {
auto skip = searchedOffset(); 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()) { if (searchedSelected < 0 || searchedSelected >= _searchResults.size()) {
searchedSelected = -1; searchedSelected = -1;
} }
@ -1035,7 +1043,7 @@ void InnerWidget::mousePressEvent(QMouseEvent *e) {
}); });
} else if (_pressed) { } else if (_pressed) {
auto row = _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()) { if (!_pinnedShiftAnimation.animating()) {
row->entry()->updateChatListEntry(); row->entry()->updateChatListEntry();
} }
@ -1050,20 +1058,20 @@ void InnerWidget::mousePressEvent(QMouseEvent *e) {
const auto row = _filterResults[_filteredPressed]; const auto row = _filterResults[_filteredPressed];
const auto list = _mode; const auto list = _mode;
row->addRipple( row->addRipple(
e->pos() - QPoint(0, filteredOffset() + _filteredPressed * st::dialogsRowHeight), e->pos() - QPoint(0, filteredOffset() + _filteredPressed * DialogsRowHeight()),
QSize(width(), st::dialogsRowHeight), QSize(width(), DialogsRowHeight()),
[=] { repaintDialogRow(list, row); }); [=] { repaintDialogRow(list, row); });
} else if (base::in_range(_peerSearchPressed, 0, _peerSearchResults.size())) { } else if (base::in_range(_peerSearchPressed, 0, _peerSearchResults.size())) {
auto &result = _peerSearchResults[_peerSearchPressed]; auto &result = _peerSearchResults[_peerSearchPressed];
auto row = &result->row; auto row = &result->row;
row->addRipple( row->addRipple(
e->pos() - QPoint(0, peerSearchOffset() + _peerSearchPressed * st::dialogsRowHeight), e->pos() - QPoint(0, peerSearchOffset() + _peerSearchPressed * DialogsRowHeight()),
QSize(width(), st::dialogsRowHeight), QSize(width(), DialogsRowHeight()),
[this, peer = result->peer] { updateSearchResult(peer); }); [this, peer = result->peer] { updateSearchResult(peer); });
} else if (base::in_range(_searchedPressed, 0, _searchResults.size())) { } else if (base::in_range(_searchedPressed, 0, _searchResults.size())) {
auto &row = _searchResults[_searchedPressed]; auto &row = _searchResults[_searchedPressed];
row->addRipple(e->pos() - QPoint(0, searchedOffset() + _searchedPressed * st::dialogsRowHeight), QSize(width(), st::dialogsRowHeight), [this, index = _searchedPressed] { row->addRipple(e->pos() - QPoint(0, searchedOffset() + _searchedPressed * DialogsRowHeight()), QSize(width(), DialogsRowHeight()), [this, index = _searchedPressed] {
rtlupdate(0, searchedOffset() + index * st::dialogsRowHeight, width(), st::dialogsRowHeight); rtlupdate(0, searchedOffset() + index * DialogsRowHeight(), width(), DialogsRowHeight());
}); });
} }
if (anim::Disabled() if (anim::Disabled()
@ -1182,7 +1190,7 @@ bool InnerWidget::updateReorderPinned(QPoint localPosition) {
auto yaddWas = _pinnedRows[_draggingIndex].yadd.current(); auto yaddWas = _pinnedRows[_draggingIndex].yadd.current();
auto shift = 0; auto shift = 0;
auto now = crl::now(); auto now = crl::now();
auto rowHeight = st::dialogsRowHeight; auto rowHeight = DialogsRowHeight();
if (_dragStart.y() > localPosition.y() && _draggingIndex > 0) { if (_dragStart.y() > localPosition.y() && _draggingIndex > 0) {
shift = -floorclamp(_dragStart.y() - localPosition.y() + (rowHeight / 2), rowHeight, 0, _draggingIndex); shift = -floorclamp(_dragStart.y() - localPosition.y() + (rowHeight / 2), rowHeight, 0, _draggingIndex);
@ -1263,11 +1271,11 @@ bool InnerWidget::pinnedShiftAnimationCallback(crl::time now) {
} }
if (updateMin >= 0) { if (updateMin >= 0) {
auto top = pinnedOffset(); auto top = pinnedOffset();
auto updateFrom = top + st::dialogsRowHeight * (updateMin - 1); auto updateFrom = top + DialogsRowHeight() * (updateMin - 1);
auto updateHeight = st::dialogsRowHeight * (updateMax - updateMin + 3); auto updateHeight = DialogsRowHeight() * (updateMax - updateMin + 3);
if (base::in_range(_aboveIndex, 0, _pinnedRows.size())) { if (base::in_range(_aboveIndex, 0, _pinnedRows.size())) {
// Always include currently dragged chat in its current and old positions. // 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()); auto aboveTopShift = qCeil(_pinnedRows[_aboveIndex].yadd.current());
accumulate_max(updateHeight, (aboveRowBottom - updateFrom) + _aboveTopShift); accumulate_max(updateHeight, (aboveRowBottom - updateFrom) + _aboveTopShift);
accumulate_max(updateHeight, (aboveRowBottom - updateFrom) + aboveTopShift); accumulate_max(updateHeight, (aboveRowBottom - updateFrom) + aboveTopShift);
@ -1441,7 +1449,7 @@ void InnerWidget::refreshDialog(Key key) {
? result.importantMoved ? result.importantMoved
: result.moved; : result.moved;
const auto rowHeight = st::dialogsRowHeight; const auto rowHeight = DialogsRowHeight();
const auto from = dialogsOffset() + moved.from * rowHeight; const auto from = dialogsOffset() + moved.from * rowHeight;
const auto to = dialogsOffset() + moved.to * rowHeight; const auto to = dialogsOffset() + moved.to * rowHeight;
if (!_dragging if (!_dragging
@ -1506,7 +1514,7 @@ int InnerWidget::defaultRowTop(not_null<Row*> row) const {
if (base::in_range(position, 0, _pinnedRows.size())) { if (base::in_range(position, 0, _pinnedRows.size())) {
top += qRound(_pinnedRows[position].yadd.current()); top += qRound(_pinnedRows[position].yadd.current());
} }
return top + position * st::dialogsRowHeight; return top + position * DialogsRowHeight();
} }
void InnerWidget::repaintDialogRow( void InnerWidget::repaintDialogRow(
@ -1517,7 +1525,7 @@ void InnerWidget::repaintDialogRow(
if (const auto folder = row->folder()) { if (const auto folder = row->folder()) {
repaintCollapsedFolderRow(folder); repaintCollapsedFolderRow(folder);
} }
update(0, defaultRowTop(row), width(), st::dialogsRowHeight); update(0, defaultRowTop(row), width(), DialogsRowHeight());
} }
} else if (_state == WidgetState::Filtered) { } else if (_state == WidgetState::Filtered) {
if (list == Mode::All) { if (list == Mode::All) {
@ -1525,9 +1533,9 @@ void InnerWidget::repaintDialogRow(
if (_filterResults[i]->key() == row->key()) { if (_filterResults[i]->key() == row->key()) {
update( update(
0, 0,
filteredOffset() + i * st::dialogsRowHeight, filteredOffset() + i * DialogsRowHeight(),
width(), width(),
st::dialogsRowHeight); DialogsRowHeight());
break; break;
} }
} }
@ -1545,7 +1553,7 @@ void InnerWidget::updateSearchResult(not_null<PeerData*> peer) {
auto index = 0, add = peerSearchOffset(); auto index = 0, add = peerSearchOffset();
for (const auto &result : _peerSearchResults) { for (const auto &result : _peerSearchResults) {
if (result->peer == peer) { if (result->peer == peer) {
rtlupdate(0, add + index * st::dialogsRowHeight, width(), st::dialogsRowHeight); rtlupdate(0, add + index * DialogsRowHeight(), width(), DialogsRowHeight());
break; break;
} }
++index; ++index;
@ -1559,7 +1567,7 @@ void InnerWidget::updateDialogRow(
QRect updateRect, QRect updateRect,
UpdateRowSections sections) { UpdateRowSections sections) {
if (updateRect.isEmpty()) { if (updateRect.isEmpty()) {
updateRect = QRect(0, 0, width(), st::dialogsRowHeight); updateRect = QRect(0, 0, width(), DialogsRowHeight());
} }
if (IsServerMsgId(-row.fullId.msg)) { if (IsServerMsgId(-row.fullId.msg)) {
if (const auto peer = row.key.peer()) { if (const auto peer = row.key.peer()) {
@ -1591,7 +1599,7 @@ void InnerWidget::updateDialogRow(
if (base::in_range(position, 0, _pinnedRows.size())) { if (base::in_range(position, 0, _pinnedRows.size())) {
top += qRound(_pinnedRows[position].yadd.current()); top += qRound(_pinnedRows[position].yadd.current());
} }
updateRow(top + position * st::dialogsRowHeight); updateRow(top + position * DialogsRowHeight());
} }
} }
} else if (_state == WidgetState::Filtered) { } else if (_state == WidgetState::Filtered) {
@ -1601,7 +1609,7 @@ void InnerWidget::updateDialogRow(
auto index = 0; auto index = 0;
for (const auto result : _filterResults) { for (const auto result : _filterResults) {
if (result->key() == row.key) { if (result->key() == row.key) {
updateRow(add + index * st::dialogsRowHeight); updateRow(add + index * DialogsRowHeight());
break; break;
} }
++index; ++index;
@ -1614,7 +1622,7 @@ void InnerWidget::updateDialogRow(
auto index = 0; auto index = 0;
for (const auto &result : _peerSearchResults) { for (const auto &result : _peerSearchResults) {
if (result->peer == peer) { if (result->peer == peer) {
updateRow(add + index * st::dialogsRowHeight); updateRow(add + index * DialogsRowHeight());
break; break;
} }
++index; ++index;
@ -1627,7 +1635,7 @@ void InnerWidget::updateDialogRow(
auto index = 0; auto index = 0;
for (const auto &result : _searchResults) { for (const auto &result : _searchResults) {
if (isSearchResultActive(result.get(), row)) { if (isSearchResultActive(result.get(), row)) {
updateRow(add + index * st::dialogsRowHeight); updateRow(add + index * DialogsRowHeight());
break; break;
} }
++index; ++index;
@ -1652,9 +1660,9 @@ void InnerWidget::updateSelectedRow(Key key) {
if (base::in_range(position, 0, _pinnedRows.size())) { if (base::in_range(position, 0, _pinnedRows.size())) {
top += qRound(_pinnedRows[position].yadd.current()); 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) { } 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) { } else if (_collapsedSelected >= 0) {
update(0, _collapsedSelected * st::dialogsImportantBarHeight, width(), st::dialogsImportantBarHeight); update(0, _collapsedSelected * st::dialogsImportantBarHeight, width(), st::dialogsImportantBarHeight);
} }
@ -1662,18 +1670,18 @@ void InnerWidget::updateSelectedRow(Key key) {
if (key) { if (key) {
for (auto i = 0, l = int(_filterResults.size()); i != l; ++i) { for (auto i = 0, l = int(_filterResults.size()); i != l; ++i) {
if (_filterResults[i]->key() == key) { if (_filterResults[i]->key() == key) {
update(0, filteredOffset() + i * st::dialogsRowHeight, width(), st::dialogsRowHeight); update(0, filteredOffset() + i * DialogsRowHeight(), width(), DialogsRowHeight());
break; break;
} }
} }
} else if (_hashtagSelected >= 0) { } else if (_hashtagSelected >= 0) {
update(0, _hashtagSelected * st::mentionHeight, width(), st::mentionHeight); update(0, _hashtagSelected * st::mentionHeight, width(), st::mentionHeight);
} else if (_filteredSelected >= 0) { } else if (_filteredSelected >= 0) {
update(0, filteredOffset() + _filteredSelected * st::dialogsRowHeight, width(), st::dialogsRowHeight); update(0, filteredOffset() + _filteredSelected * DialogsRowHeight(), width(), DialogsRowHeight());
} else if (_peerSearchSelected >= 0) { } else if (_peerSearchSelected >= 0) {
update(0, peerSearchOffset() + _peerSearchSelected * st::dialogsRowHeight, width(), st::dialogsRowHeight); update(0, peerSearchOffset() + _peerSearchSelected * DialogsRowHeight(), width(), DialogsRowHeight());
} else if (_searchedSelected >= 0) { } 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() const auto collapsedHasArchive = !_collapsedRows.empty()
&& (_collapsedRows.back()->folder != nullptr); && (_collapsedRows.back()->folder != nullptr);
const auto archiveIsCollapsed = (archive != nullptr) const auto archiveIsCollapsed = (archive != nullptr)
&& session().settings().archiveCollapsed(); && (session().settings().archiveCollapsed() || cDialogListLines() == 1);
const auto archiveIsInMainMenu = (archive != nullptr) const auto archiveIsInMainMenu = (archive != nullptr)
&& session().settings().archiveInMainMenu(); && session().settings().archiveInMainMenu();
return archiveIsInMainMenu return archiveIsInMainMenu
@ -2178,15 +2186,15 @@ void InnerWidget::refresh(bool toTop) {
if (!_addContactLnk->isHidden()) _addContactLnk->hide(); if (!_addContactLnk->isHidden()) _addContactLnk->hide();
} }
} else { } else {
h = dialogsOffset() + shownDialogs()->size() * st::dialogsRowHeight; h = dialogsOffset() + shownDialogs()->size() * DialogsRowHeight();
if (!_addContactLnk->isHidden()) _addContactLnk->hide(); if (!_addContactLnk->isHidden()) _addContactLnk->hide();
} }
} else if (_state == WidgetState::Filtered) { } else if (_state == WidgetState::Filtered) {
if (!_addContactLnk->isHidden()) _addContactLnk->hide(); if (!_addContactLnk->isHidden()) _addContactLnk->hide();
if (_waitingForSearch) { 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 { } else {
h = searchedOffset() + (_searchResults.size() * st::dialogsRowHeight); h = searchedOffset() + (_searchResults.size() * DialogsRowHeight());
} }
} }
resize(width(), h); resize(width(), h);
@ -2339,8 +2347,8 @@ void InnerWidget::selectSkip(int32 direction) {
if (_collapsedSelected >= 0 || _selected) { if (_collapsedSelected >= 0 || _selected) {
const auto fromY = (_collapsedSelected >= 0) const auto fromY = (_collapsedSelected >= 0)
? (_collapsedSelected * st::dialogsImportantBarHeight) ? (_collapsedSelected * st::dialogsImportantBarHeight)
: (dialogsOffset() + _selected->pos() * st::dialogsRowHeight); : (dialogsOffset() + _selected->pos() * DialogsRowHeight());
emit mustScrollTo(fromY, fromY + st::dialogsRowHeight); emit mustScrollTo(fromY, fromY + DialogsRowHeight());
} }
} else if (_state == WidgetState::Filtered) { } else if (_state == WidgetState::Filtered) {
if (_hashtagResults.empty() && _filterResults.empty() && _peerSearchResults.empty() && _searchResults.empty()) { 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())) { if (base::in_range(_hashtagSelected, 0, _hashtagResults.size())) {
emit mustScrollTo(_hashtagSelected * st::mentionHeight, (_hashtagSelected + 1) * st::mentionHeight); emit mustScrollTo(_hashtagSelected * st::mentionHeight, (_hashtagSelected + 1) * st::mentionHeight);
} else if (base::in_range(_filteredSelected, 0, _filterResults.size())) { } 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())) { } 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 { } 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(); update();
@ -2399,32 +2407,32 @@ void InnerWidget::scrollToEntry(const RowDescriptor &entry) {
int32 fromY = -1; int32 fromY = -1;
if (_state == WidgetState::Default) { if (_state == WidgetState::Default) {
if (auto row = shownDialogs()->getRow(entry.key)) { if (auto row = shownDialogs()->getRow(entry.key)) {
fromY = dialogsOffset() + row->pos() * st::dialogsRowHeight; fromY = dialogsOffset() + row->pos() * DialogsRowHeight();
} }
} else if (_state == WidgetState::Filtered) { } else if (_state == WidgetState::Filtered) {
for (int32 i = 0, c = _searchResults.size(); i < c; ++i) { for (int32 i = 0, c = _searchResults.size(); i < c; ++i) {
if (isSearchResultActive(_searchResults[i].get(), entry)) { if (isSearchResultActive(_searchResults[i].get(), entry)) {
fromY = searchedOffset() + i * st::dialogsRowHeight; fromY = searchedOffset() + i * DialogsRowHeight();
break; break;
} }
} }
if (fromY < 0) { if (fromY < 0) {
for (auto i = 0, c = int(_filterResults.size()); i != c; ++i) { for (auto i = 0, c = int(_filterResults.size()); i != c; ++i) {
if (_filterResults[i]->key() == entry.key) { if (_filterResults[i]->key() == entry.key) {
fromY = filteredOffset() + (i * st::dialogsRowHeight); fromY = filteredOffset() + (i * DialogsRowHeight());
break; break;
} }
} }
} }
} }
if (fromY >= 0) { if (fromY >= 0) {
emit mustScrollTo(fromY, fromY + st::dialogsRowHeight); emit mustScrollTo(fromY, fromY + DialogsRowHeight());
} }
} }
void InnerWidget::selectSkipPage(int32 pixels, int32 direction) { void InnerWidget::selectSkipPage(int32 pixels, int32 direction) {
clearMouseSelection(); clearMouseSelection();
int toSkip = pixels / int(st::dialogsRowHeight); int toSkip = pixels / int(DialogsRowHeight());
if (_state == WidgetState::Default) { if (_state == WidgetState::Default) {
if (!_selected) { if (!_selected) {
if (direction > 0 && shownDialogs()->size() > _skipTopDialogs) { if (direction > 0 && shownDialogs()->size() > _skipTopDialogs) {
@ -2450,8 +2458,8 @@ void InnerWidget::selectSkipPage(int32 pixels, int32 direction) {
if (_collapsedSelected >= 0 || _selected) { if (_collapsedSelected >= 0 || _selected) {
const auto fromY = (_collapsedSelected >= 0) const auto fromY = (_collapsedSelected >= 0)
? (_collapsedSelected * st::dialogsImportantBarHeight) ? (_collapsedSelected * st::dialogsImportantBarHeight)
: (dialogsOffset() + _selected->pos() * st::dialogsRowHeight); : (dialogsOffset() + _selected->pos() * DialogsRowHeight());
emit mustScrollTo(fromY, fromY + st::dialogsRowHeight); emit mustScrollTo(fromY, fromY + DialogsRowHeight());
} }
} else { } else {
return selectSkip(direction * toSkip); return selectSkip(direction * toSkip);
@ -2466,10 +2474,10 @@ void InnerWidget::loadPeerPhotos() {
auto yTo = _visibleTop + (_visibleBottom - _visibleTop) * (PreloadHeightsCount + 1); auto yTo = _visibleTop + (_visibleBottom - _visibleTop) * (PreloadHeightsCount + 1);
session().downloader().clearPriorities(); session().downloader().clearPriorities();
if (_state == WidgetState::Default) { if (_state == WidgetState::Default) {
auto otherStart = shownDialogs()->size() * st::dialogsRowHeight; auto otherStart = shownDialogs()->size() * DialogsRowHeight();
if (yFrom < otherStart) { if (yFrom < otherStart) {
for (auto i = shownDialogs()->cfind(yFrom, st::dialogsRowHeight), end = shownDialogs()->cend(); i != end; ++i) { for (auto i = shownDialogs()->cfind(yFrom, DialogsRowHeight()), end = shownDialogs()->cend(); i != end; ++i) {
if (((*i)->pos() * st::dialogsRowHeight) >= yTo) { if (((*i)->pos() * DialogsRowHeight()) >= yTo) {
break; break;
} }
(*i)->entry()->loadUserpic(); (*i)->entry()->loadUserpic();
@ -2480,10 +2488,10 @@ void InnerWidget::loadPeerPhotos() {
} }
yTo -= otherStart; yTo -= otherStart;
} else if (_state == WidgetState::Filtered) { } else if (_state == WidgetState::Filtered) {
int32 from = (yFrom - filteredOffset()) / st::dialogsRowHeight; int32 from = (yFrom - filteredOffset()) / DialogsRowHeight();
if (from < 0) from = 0; if (from < 0) from = 0;
if (from < _filterResults.size()) { 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(); if (to > _filterResults.size()) to = _filterResults.size();
for (; from < to; ++from) { 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 < 0) from = 0;
if (from < _peerSearchResults.size()) { 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(); if (to > _peerSearchResults.size()) to = _peerSearchResults.size();
for (; from < to; ++from) { for (; from < to; ++from) {
_peerSearchResults[from]->peer->loadUserpic(); _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 < 0) from = 0;
if (from < _searchResults.size()) { 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(); if (to > _searchResults.size()) to = _searchResults.size();
for (; from < to; ++from) { for (; from < to; ++from) {
@ -2860,7 +2868,7 @@ void InnerWidget::userOnlineUpdated(const Notify::PeerUpdate &update) {
const auto size = st::dialogsOnlineBadgeSize; const auto size = st::dialogsOnlineBadgeSize;
const auto stroke = st::dialogsOnlineBadgeStroke; const auto stroke = st::dialogsOnlineBadgeStroke;
const auto skip = st::dialogsOnlineBadgeSkip; const auto skip = st::dialogsOnlineBadgeSkip;
const auto edge = st::dialogsPadding.x() + st::dialogsPhotoSize; const auto edge = st::dialogsPadding.x() + DialogsPhotoSize();
const auto updateRect = QRect( const auto updateRect = QRect(
edge - skip.x() - size, edge - skip.x() - size,
edge - skip.y() - size, edge - skip.y() - size,
@ -2893,11 +2901,11 @@ void InnerWidget::userOnlineUpdated(const Notify::PeerUpdate &update) {
[](not_null<Row*> row) { return row->history(); }); [](not_null<Row*> row) { return row->history(); });
const auto index = (i - begin(_filterResults)); const auto index = (i - begin(_filterResults));
const auto row = (i == end(_filterResults)) ? nullptr : i->get(); 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) { if (const auto &[row, top] = findRow(history); row != nullptr) {
const auto visible = (top < _visibleBottom) const auto visible = (top < _visibleBottom)
&& (top + st::dialogsRowHeight > _visibleTop); && (top + DialogsRowHeight() > _visibleTop);
row->setOnline( row->setOnline(
Data::OnlineTextActive(user, base::unixtime::now()), Data::OnlineTextActive(user, base::unixtime::now()),
visible ? Fn<void()>(crl::guard(this, repaint)) : nullptr); visible ? Fn<void()>(crl::guard(this, repaint)) : nullptr);

View file

@ -77,15 +77,18 @@ void PaintNarrowCounter(
int unreadCount, int unreadCount,
bool active, bool active,
bool unreadMuted, bool unreadMuted,
bool mentionMuted) { bool mentionMuted,
int lines = 2) {
auto skipBeforeMention = 0; auto skipBeforeMention = 0;
if (displayUnreadCounter || displayUnreadMark) { if (displayUnreadCounter || displayUnreadMark) {
auto counter = (unreadCount > 0) auto counter = (unreadCount > 0)
? QString::number(unreadCount) ? QString::number(unreadCount)
: QString(); : QString();
const auto allowDigits = displayMentionBadge ? 1 : 3; const auto allowDigits = displayMentionBadge ? 1 : 3;
auto unreadRight = st::dialogsPadding.x() + st::dialogsPhotoSize; auto unreadRight = st::dialogsPadding.x() + (cDialogListLines() == 1 ? st::dialogsUnreadHeight : st::dialogsPhotoSize);
auto unreadTop = st::dialogsPadding.y() + st::dialogsPhotoSize - st::dialogsUnreadHeight; auto unreadTop = (lines == 1
? st::dialogsPadding.y()
: st::dialogsPadding.y() + st::dialogsPhotoSize - st::dialogsUnreadHeight);
auto unreadWidth = 0; auto unreadWidth = 0;
UnreadBadgeStyle st; UnreadBadgeStyle st;
@ -96,8 +99,10 @@ void PaintNarrowCounter(
} }
if (displayMentionBadge) { if (displayMentionBadge) {
auto counter = qsl("@"); auto counter = qsl("@");
auto unreadRight = st::dialogsPadding.x() + st::dialogsPhotoSize - skipBeforeMention; auto unreadRight = st::dialogsPadding.x() + (cDialogListLines() == 1 ? st::dialogsUnreadHeight : st::dialogsPhotoSize) - skipBeforeMention;
auto unreadTop = st::dialogsPadding.y() + st::dialogsPhotoSize - st::dialogsUnreadHeight; auto unreadTop = (lines == 1
? st::dialogsPadding.y()
: st::dialogsPadding.y() + st::dialogsPhotoSize - st::dialogsUnreadHeight);
auto unreadWidth = 0; auto unreadWidth = 0;
UnreadBadgeStyle st; UnreadBadgeStyle st;
@ -212,6 +217,173 @@ enum class Flag {
}; };
inline constexpr bool is_flag_type(Flag) { return true; } inline constexpr bool is_flag_type(Flag) { return true; }
template <typename PaintItemCallback, typename PaintCounterCallback>
void paintOneLineRow(
Painter &p,
not_null<const BasicRow*> row,
not_null<Entry*> entry,
Dialogs::Key chat,
PeerData *from,
const HiddenSenderInfo *hiddenSenderInfo,
HistoryItem *item,
const Data::Draft *draft,
QDateTime date,
int fullWidth,
base::flags<Flag> 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 <typename PaintItemCallback, typename PaintCounterCallback> template <typename PaintItemCallback, typename PaintCounterCallback>
void paintRow( void paintRow(
Painter &p, Painter &p,
@ -659,6 +831,10 @@ void RowPainter::paint(
? history->hasUnreadMentions() ? history->hasUnreadMentions()
: false; : false;
const auto displayUnreadCounter = [&] { const auto displayUnreadCounter = [&] {
if (fullWidth < st::columnMinimalWidthLeft && cDialogListLines() == 1) {
return false;
}
if (displayMentionBadge if (displayMentionBadge
&& unreadCount == 1 && unreadCount == 1
&& item && item
@ -689,9 +865,12 @@ void RowPainter::paint(
| (allowUserOnline ? Flag::AllowUserOnline : Flag(0)) | (allowUserOnline ? Flag::AllowUserOnline : Flag(0))
| (peer && peer->isSelf() ? Flag::SavedMessages : Flag(0)); | (peer && peer->isSelf() ? Flag::SavedMessages : Flag(0));
const auto paintItemCallback = [&](int nameleft, int namewidth) { const auto paintItemCallback = [&](int nameleft, int namewidth) {
const auto texttop = st::dialogsPadding.y() const auto texttop = (cDialogListLines() == 1
+ st::msgNameFont->height ? st::dialogsPadding.y()
+ st::dialogsSkip; : st::dialogsPadding.y()
+ st::msgNameFont->height
+ st::dialogsSkip);
const auto availableWidth = PaintWideCounter( const auto availableWidth = PaintWideCounter(
p, p,
texttop, texttop,
@ -706,36 +885,40 @@ void RowPainter::paint(
selected, selected,
unreadMuted, unreadMuted,
mentionMuted); mentionMuted);
const auto &color = active if (cDialogListLines() > 1 || flags & Flag::SearchResult) {
? st::dialogsTextFgServiceActive const auto &color = active
: (selected ? st::dialogsTextFgServiceActive
? st::dialogsTextFgServiceOver : (selected
: st::dialogsTextFgService); ? st::dialogsTextFgServiceOver
const auto itemRect = QRect( : st::dialogsTextFgService);
nameleft, const auto itemRect = QRect(
texttop, nameleft,
availableWidth, texttop,
st::dialogsTextFont->height); availableWidth,
const auto actionWasPainted = history ? history->paintSendAction( st::dialogsTextFont->height);
p, const auto actionWasPainted = history ? history->paintSendAction(
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, p,
itemRect, itemRect.x(),
active, itemRect.y(),
selected, itemRect.width(),
HistoryItem::DrawInDialog::Normal, fullWidth,
entry->textCachedFor, color,
entry->lastItemTextCache); 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 = [&] { const auto paintCounterCallback = [&] {
PaintNarrowCounter( PaintNarrowCounter(
@ -746,23 +929,42 @@ void RowPainter::paint(
unreadCount, unreadCount,
active, active,
unreadMuted, unreadMuted,
mentionMuted); mentionMuted,
cDialogListLines());
}; };
paintRow( if (cDialogListLines() == 1) {
p, paintOneLineRow(
row, p,
entry, row,
row->key(), entry,
from, row->key(),
nullptr, from,
item, nullptr,
cloudDraft, item,
displayDate, cloudDraft,
fullWidth, displayDate,
flags, fullWidth,
ms, flags,
paintItemCallback, ms,
paintCounterCallback); paintItemCallback,
paintCounterCallback);
} else {
paintRow(
p,
row,
entry,
row->key(),
from,
nullptr,
item,
cloudDraft,
displayDate,
fullWidth,
flags,
ms,
paintItemCallback,
paintCounterCallback);
}
} }
void RowPainter::paint( void RowPainter::paint(
@ -819,11 +1021,19 @@ void RowPainter::paint(
&& !displayMentionBadge && !displayMentionBadge
&& unreadMark; && unreadMark;
const auto displayPinnedIcon = false; 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 paintItemCallback = [&](int nameleft, int namewidth) {
const auto texttop = st::dialogsPadding.y() const auto texttop = (cDialogListLines() == 1
+ st::msgNameFont->height ? st::dialogsPadding.y()
+ st::dialogsSkip; : st::dialogsPadding.y()
+ st::msgNameFont->height
+ st::dialogsSkip);
const auto availableWidth = PaintWideCounter( const auto availableWidth = PaintWideCounter(
p, p,
texttop, texttop,
@ -839,19 +1049,23 @@ void RowPainter::paint(
unreadMuted, unreadMuted,
mentionMuted); mentionMuted);
const auto itemRect = QRect( if (cDialogListLines() > 1 || flags & Flag::SearchResult) {
nameleft, const auto itemRect = QRect(
texttop, nameleft,
availableWidth, texttop,
st::dialogsTextFont->height); availableWidth,
item->drawInDialog( st::dialogsTextFont->height);
p, item->drawInDialog(
itemRect, p,
active, itemRect,
selected, active,
drawInDialogWay, selected,
row->_cacheFor, drawInDialogWay,
row->_cache); row->_cacheFor,
row->_cache);
}
return availableWidth;
}; };
const auto paintCounterCallback = [&] { const auto paintCounterCallback = [&] {
PaintNarrowCounter( PaintNarrowCounter(
@ -862,34 +1076,46 @@ void RowPainter::paint(
unreadCount, unreadCount,
active, active,
unreadMuted, unreadMuted,
mentionMuted); mentionMuted,
cDialogListLines());
}; };
const auto showSavedMessages = history->peer->isSelf() if (cDialogListLines() == 1) {
&& !row->searchInChat(); paintOneLineRow(
const auto flags = (active ? Flag::Active : Flag(0)) p,
| (selected ? Flag::Selected : Flag(0)) row,
| Flag::SearchResult history,
| (showSavedMessages ? Flag::SavedMessages : Flag(0))/* // #feed history,
| (row->searchInChat().feed() ? Flag::FeedSearchResult : Flag(0))*/; from,
paintRow( hiddenSenderInfo,
p, item,
row, cloudDraft,
history, ItemDateTime(item),
history, fullWidth,
from, flags,
hiddenSenderInfo, ms,
item, paintItemCallback,
cloudDraft, paintCounterCallback);
ItemDateTime(item), } else {
fullWidth, paintRow(
flags, p,
ms, row,
paintItemCallback, history,
paintCounterCallback); history,
from,
hiddenSenderInfo,
item,
cloudDraft,
ItemDateTime(item),
fullWidth,
flags,
ms,
paintItemCallback,
paintCounterCallback);
}
} }
QRect RowPainter::sendActionAnimationRect(int animationWidth, int animationHeight, int fullWidth, bool textUpdated) { 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 namewidth = fullWidth - nameleft - st::dialogsPadding.x();
auto texttop = st::dialogsPadding.y() + st::msgNameFont->height + st::dialogsSkip; auto texttop = st::dialogsPadding.y() + st::msgNameFont->height + st::dialogsSkip;
return QRect(nameleft, texttop, textUpdated ? namewidth : animationWidth, animationHeight); return QRect(nameleft, texttop, textUpdated ? namewidth : animationWidth, animationHeight);

View file

@ -146,7 +146,7 @@ void BasicRow::PaintOnlineFrame(
q, q,
0, 0,
0, 0,
st::dialogsPhotoSize); (cDialogListLines() == 1 ? st::dialogsUnreadHeight : st::dialogsPhotoSize));
PainterHighQualityEnabler hq(q); PainterHighQualityEnabler hq(q);
q.setCompositionMode(QPainter::CompositionMode_Source); q.setCompositionMode(QPainter::CompositionMode_Source);
@ -154,7 +154,7 @@ void BasicRow::PaintOnlineFrame(
const auto size = st::dialogsOnlineBadgeSize; const auto size = st::dialogsOnlineBadgeSize;
const auto stroke = st::dialogsOnlineBadgeStroke; const auto stroke = st::dialogsOnlineBadgeStroke;
const auto skip = st::dialogsOnlineBadgeSkip; 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); const auto shrink = (size / 2) * (1. - data->online);
auto pen = QPen(Qt::transparent); auto pen = QPen(Qt::transparent);
@ -182,13 +182,13 @@ void BasicRow::paintUserpic(
const auto online = _onlineUserpic const auto online = _onlineUserpic
? _onlineUserpic->animation.value(_online ? 1. : 0.) ? _onlineUserpic->animation.value(_online ? 1. : 0.)
: (_online ? 1. : 0.); : (_online ? 1. : 0.);
if (!allowOnline || online == 0.) { if (!allowOnline || cDialogListLines() == 1 || online == 0.) {
peer->paintUserpicLeft( peer->paintUserpicLeft(
p, p,
st::dialogsPadding.x(), st::dialogsPadding.x(),
st::dialogsPadding.y(), st::dialogsPadding.y(),
fullWidth, fullWidth,
st::dialogsPhotoSize); (cDialogListLines() == 1 ? st::dialogsUnreadHeight : st::dialogsPhotoSize));
if (!allowOnline || !_online) { if (!allowOnline || !_online) {
_onlineUserpic = nullptr; _onlineUserpic = nullptr;
} }
@ -197,8 +197,8 @@ void BasicRow::paintUserpic(
ensureOnlineUserpic(); ensureOnlineUserpic();
if (_onlineUserpic->frame.isNull()) { if (_onlineUserpic->frame.isNull()) {
_onlineUserpic->frame = QImage( _onlineUserpic->frame = QImage(
st::dialogsPhotoSize * cRetinaFactor(), (cDialogListLines() == 1 ? st::dialogsUnreadHeight : st::dialogsPhotoSize) * cRetinaFactor(),
st::dialogsPhotoSize * cRetinaFactor(), (cDialogListLines() == 1 ? st::dialogsUnreadHeight : st::dialogsPhotoSize) * cRetinaFactor(),
QImage::Format_ARGB32_Premultiplied); QImage::Format_ARGB32_Premultiplied);
_onlineUserpic->frame.setDevicePixelRatio(cRetinaFactor()); _onlineUserpic->frame.setDevicePixelRatio(cRetinaFactor());
} }

View file

@ -1446,7 +1446,7 @@ void Widget::updateControlsGeometry() {
_forwardCancel->moveToLeft(0, filterAreaTop); _forwardCancel->moveToLeft(0, filterAreaTop);
filterAreaTop += st::dialogsForwardHeight; 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 smallLayoutRatio = (width() < st::columnMinimalWidthLeft) ? (st::columnMinimalWidthLeft - width()) / float64(st::columnMinimalWidthLeft - smallLayoutWidth) : 0.;
auto filterLeft = st::dialogsFilterPadding.x() + _mainMenuToggle->width() + st::dialogsFilterPadding.x(); auto filterLeft = st::dialogsFilterPadding.x() + _mainMenuToggle->width() + st::dialogsFilterPadding.x();
auto filterRight = (Global::LocalPasscode() ? (st::dialogsFilterPadding.x() + _lockUnlock->width()) : st::dialogsFilterSkip) + 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) { void Widget::onDialogMoved(int movedFrom, int movedTo) {
int32 st = _scroll->scrollTop(); int32 st = _scroll->scrollTop();
if (st > movedTo && st < movedFrom) { if (st > movedTo && st < movedFrom) {
_scroll->scrollToY(st + st::dialogsRowHeight); _scroll->scrollToY(st + (cDialogListLines() == 1 ? st::dialogsImportantBarHeight : st::dialogsRowHeight));
} }
} }

View file

@ -261,4 +261,6 @@ bool AddCustomScale(int scale) {
void ClearCustomScales() { void ClearCustomScales() {
gInterfaceScales.clear(); gInterfaceScales.clear();
} }
int gDialogListLines = 2;

View file

@ -225,4 +225,5 @@ using ScaleVector = std::vector<int>;
DeclareRefSetting(ScaleVector, InterfaceScales); DeclareRefSetting(ScaleVector, InterfaceScales);
bool HasCustomScales(); bool HasCustomScales();
bool AddCustomScale(int scale); bool AddCustomScale(int scale);
void ClearCustomScales(); void ClearCustomScales();
DeclareSetting(int, DialogListLines);

View file

@ -620,14 +620,16 @@ void FolderFiller::addTogglesForArchive() {
return; return;
} }
const auto controller = _controller; const auto controller = _controller;
const auto hidden = controller->session().settings().archiveCollapsed(); if (cDialogListLines() != 1) {
const auto text = hidden const auto hidden = (controller->session().settings().archiveCollapsed());
? tr::lng_context_archive_expand(tr::now) const auto text = hidden
: tr::lng_context_archive_collapse(tr::now); ? tr::lng_context_archive_expand(tr::now)
_addAction(text, [=] { : tr::lng_context_archive_collapse(tr::now);
controller->session().settings().setArchiveCollapsed(!hidden); _addAction(text, [=] {
controller->session().saveSettingsDelayed(); controller->session().settings().setArchiveCollapsed(!hidden);
}); controller->session().saveSettingsDelayed();
});
}
_addAction(tr::lng_context_archive_to_menu(tr::now), [=] { _addAction(tr::lng_context_archive_to_menu(tr::now), [=] {
auto toast = Ui::Toast::Config(); auto toast = Ui::Toast::Config();

View file

@ -309,7 +309,7 @@ bool SessionController::isGifPausedAtLeastFor(GifPauseReason reason) const {
} }
int SessionController::dialogsSmallColumnWidth() 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 { int SessionController::minimalThreeColumnWidth() const {