Show chat previews in suggestions.

This commit is contained in:
John Preston 2024-05-31 16:49:59 +04:00
parent f9f51b4e41
commit 521c17b76c
3 changed files with 89 additions and 19 deletions

View file

@ -36,6 +36,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "styles/style_widgets.h"
#include <xxhash.h> // XXH64.
#include <QtWidgets/QApplication>
[[nodiscard]] PeerListRowId UniqueRowIdFromString(const QString &d) {
return XXH64(d.data(), d.size() * sizeof(ushort), 0);
@ -1552,13 +1553,24 @@ void PeerListContent::handleMouseMove(QPoint globalPosition) {
&& *_lastMousePosition == globalPosition) {
return;
}
if (_trackPressStart
&& ((*_trackPressStart - globalPosition).manhattanLength()
> QApplication::startDragDistance())) {
_trackPressStart = std::nullopt;
_controller->rowTrackPressCancel();
}
selectByMouse(globalPosition);
}
void PeerListContent::cancelPress() {
setPressed(Selected());
}
void PeerListContent::mousePressEvent(QMouseEvent *e) {
_pressButton = e->button();
selectByMouse(e->globalPos());
setPressed(_selected);
_trackPressStart = {};
if (auto row = getRow(_selected.index)) {
auto updateCallback = [this, row, hint = _selected.index] {
updateRow(row, hint);
@ -1586,8 +1598,11 @@ void PeerListContent::mousePressEvent(QMouseEvent *e) {
row->addRipple(_st.item, maskGenerator, point, std::move(updateCallback));
}
}
if (_pressButton == Qt::LeftButton && _controller->rowTrackPress(row)) {
_trackPressStart = e->globalPos();
}
}
if (anim::Disabled() && !_selected.element) {
if (anim::Disabled() && !_trackPressStart && !_selected.element) {
mousePressReleased(e->button());
}
}
@ -1597,6 +1612,9 @@ void PeerListContent::mouseReleaseEvent(QMouseEvent *e) {
}
void PeerListContent::mousePressReleased(Qt::MouseButton button) {
_trackPressStart = {};
_controller->rowTrackPressCancel();
updateRow(_pressed.index);
updateRow(_selected.index);

View file

@ -347,6 +347,7 @@ public:
virtual void peerListSortRows(Fn<bool(const PeerListRow &a, const PeerListRow &b)> compare) = 0;
virtual int peerListPartitionRows(Fn<bool(const PeerListRow &a)> border) = 0;
virtual std::shared_ptr<Main::SessionShow> peerListUiShow() = 0;
virtual void peerListCancelPress() = 0;
template <typename PeerDataRange>
void peerListAddSelectedPeers(PeerDataRange &&range) {
@ -478,6 +479,12 @@ public:
}
}
virtual bool rowTrackPress(not_null<PeerListRow*> row) {
return false;
}
virtual void rowTrackPressCancel() {
}
virtual void loadMoreRows() {
}
virtual void itemDeselectedHook(not_null<PeerData*> peer) {
@ -655,6 +662,7 @@ public:
void refreshRows();
void mouseLeftGeometry();
void cancelPress();
void setSearchMode(PeerListSearchMode mode);
void changeCheckState(
@ -829,6 +837,7 @@ private:
bool _mouseSelection = false;
std::optional<QPoint> _lastMousePosition;
Qt::MouseButton _pressButton = Qt::LeftButton;
std::optional<QPoint> _trackPressStart;
rpl::event_stream<Ui::ScrollToRequest> _scrollToRequests;
@ -991,6 +1000,9 @@ public:
not_null<PeerListRow*> row,
bool highlightRow,
Fn<void(not_null<Ui::PopupMenu*>)> destroyed = nullptr) override;
void peerListCancelPress() override {
_content->cancelPress();
}
protected:
not_null<PeerListContent*> content() const {

View file

@ -86,8 +86,25 @@ private:
};
class ControllerWithPreviews : public PeerListController {
public:
explicit ControllerWithPreviews(
not_null<Window::SessionController*> window);
[[nodiscard]] not_null<Window::SessionController*> window() const {
return _window;
}
bool rowTrackPress(not_null<PeerListRow*> row) override;
void rowTrackPressCancel() override;
private:
const not_null<Window::SessionController*> _window;
};
class RecentsController final
: public PeerListController
: public ControllerWithPreviews
, public base::has_weak_ptr {
public:
RecentsController(
@ -115,7 +132,6 @@ private:
void subscribeToEvents();
[[nodiscard]] Fn<void()> removeAllCallback();
const not_null<Window::SessionController*> _window;
RecentPeersList _recent;
rpl::variable<int> _count;
rpl::event_stream<not_null<PeerData*>> _chosen;
@ -138,7 +154,7 @@ private:
};
class MyChannelsController final
: public PeerListController
: public ControllerWithPreviews
, public base::has_weak_ptr {
public:
explicit MyChannelsController(
@ -163,7 +179,6 @@ private:
void appendRow(not_null<ChannelData*> channel);
void fill(bool force = false);
const not_null<Window::SessionController*> _window;
std::vector<not_null<History*>> _channels;
rpl::variable<Ui::RpWidget*> _toggleExpanded = nullptr;
rpl::variable<int> _count = 0;
@ -174,7 +189,7 @@ private:
};
class RecommendationsController final
: public PeerListController
: public ControllerWithPreviews
, public base::has_weak_ptr {
public:
explicit RecommendationsController(
@ -201,7 +216,6 @@ private:
void setupDivider();
void appendRow(not_null<ChannelData*> channel);
const not_null<Window::SessionController*> _window;
rpl::variable<int> _count;
History *_activeHistory = nullptr;
bool _requested = false;
@ -404,10 +418,36 @@ const style::PeerListItem &ChannelRow::computeSt(
return _active ? st::recentPeersItemActive : st::recentPeersItem;
}
ControllerWithPreviews::ControllerWithPreviews(
not_null<Window::SessionController*> window)
: _window(window) {
}
bool ControllerWithPreviews::rowTrackPress(not_null<PeerListRow*> row) {
const auto peer = row->peer();
const auto history = peer->owner().history(peer);
if (base::IsAltPressed()) {
_window->showChatPreview({ history, FullMsgId() });
delegate()->peerListCancelPress();
return false;
}
const auto point = delegate()->peerListLastRowMousePosition();
const auto &st = computeListSt().item;
if (point && point->x() < st.photoPosition.x() + st.photoSize) {
_window->scheduleChatPreview({ history, FullMsgId() });
return true;
}
return false;
}
void ControllerWithPreviews::rowTrackPressCancel() {
_window->cancelScheduledPreview();
}
RecentsController::RecentsController(
not_null<Window::SessionController*> window,
RecentPeersList list)
: _window(window)
: ControllerWithPreviews(window)
, _recent(std::move(list)) {
}
@ -429,7 +469,7 @@ void RecentsController::rowClicked(not_null<PeerListRow*> row) {
Fn<void()> RecentsController::removeAllCallback() {
const auto weak = base::make_weak(this);
const auto session = &_window->session();
const auto session = &this->session();
return crl::guard(session, [=] {
if (weak) {
_count = 0;
@ -450,7 +490,7 @@ base::unique_qptr<Ui::PopupMenu> RecentsController::rowContextMenu(
st::popupMenuWithIcons);
const auto peer = row->peer();
const auto weak = base::make_weak(this);
const auto session = &_window->session();
const auto session = &this->session();
const auto removeOne = crl::guard(session, [=] {
if (weak) {
const auto rowId = peer->id.value;
@ -463,7 +503,7 @@ base::unique_qptr<Ui::PopupMenu> RecentsController::rowContextMenu(
session->recentPeers().remove(peer);
});
FillEntryMenu(Ui::Menu::CreateAddActionCallback(result), {
.controller = _window,
.controller = window(),
.peer = peer,
.removeOneText = tr::lng_recent_remove(tr::now),
.removeOne = removeOne,
@ -475,7 +515,7 @@ base::unique_qptr<Ui::PopupMenu> RecentsController::rowContextMenu(
}
Main::Session &RecentsController::session() const {
return _window->session();
return window()->session();
}
QString RecentsController::savedMessagesChatStatus() const {
@ -496,7 +536,7 @@ void RecentsController::setupDivider() {
tr::lng_recent_clear(tr::now),
st::searchedBarLink);
clear->setClickedCallback(RemoveAllConfirm(
_window,
window(),
tr::lng_recent_clear_sure(tr::now),
removeAllCallback()));
rpl::combine(
@ -555,7 +595,7 @@ void RecentsController::subscribeToEvents() {
MyChannelsController::MyChannelsController(
not_null<Window::SessionController*> window)
: _window(window) {
: ControllerWithPreviews(window) {
}
void MyChannelsController::prepare() {
@ -679,7 +719,7 @@ base::unique_qptr<Ui::PopupMenu> MyChannelsController::rowContextMenu(
const auto peer = row->peer();
const auto addAction = Ui::Menu::CreateAddActionCallback(result);
Window::FillDialogsEntryMenu(
_window,
window(),
Dialogs::EntryState{
.key = peer->owner().history(peer),
.section = Dialogs::EntryState::Section::ContextMenu,
@ -689,7 +729,7 @@ base::unique_qptr<Ui::PopupMenu> MyChannelsController::rowContextMenu(
}
Main::Session &MyChannelsController::session() const {
return _window->session();
return window()->session();
}
void MyChannelsController::setupDivider() {
@ -760,7 +800,7 @@ void MyChannelsController::setupDivider() {
RecommendationsController::RecommendationsController(
not_null<Window::SessionController*> window)
: _window(window) {
: ControllerWithPreviews(window) {
}
void RecommendationsController::prepare() {
@ -795,7 +835,7 @@ void RecommendationsController::fill() {
delegate()->peerListRefreshRows();
_count = delegate()->peerListFullRowsCount();
_window->activeChatValue() | rpl::start_with_next([=](const Key &key) {
window()->activeChatValue() | rpl::start_with_next([=](const Key &key) {
const auto history = key.history();
if (_activeHistory == history) {
return;
@ -841,7 +881,7 @@ base::unique_qptr<Ui::PopupMenu> RecommendationsController::rowContextMenu(
}
Main::Session &RecommendationsController::session() const {
return _window->session();
return window()->session();
}
void RecommendationsController::setupDivider() {