mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-18 07:07:08 +02:00
Empty preview widget on long userpic press.
This commit is contained in:
parent
ef2aa05197
commit
4427ae4306
6 changed files with 234 additions and 7 deletions
Telegram
CMakeLists.txt
SourceFiles
|
@ -781,6 +781,8 @@ PRIVATE
|
|||
history/view/history_view_about_view.h
|
||||
history/view/history_view_bottom_info.cpp
|
||||
history/view/history_view_bottom_info.h
|
||||
history/view/history_view_chat_preview.cpp
|
||||
history/view/history_view_chat_preview.h
|
||||
history/view/history_view_contact_status.cpp
|
||||
history/view/history_view_contact_status.h
|
||||
history/view/history_view_context_menu.cpp
|
||||
|
|
|
@ -15,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "dialogs/dialogs_widget.h"
|
||||
#include "dialogs/dialogs_search_from_controllers.h"
|
||||
#include "dialogs/dialogs_search_tags.h"
|
||||
#include "history/view/history_view_chat_preview.h"
|
||||
#include "history/view/history_view_context_menu.h"
|
||||
#include "history/history.h"
|
||||
#include "history/history_item.h"
|
||||
|
@ -80,6 +81,7 @@ namespace {
|
|||
|
||||
constexpr auto kHashtagResultsLimit = 5;
|
||||
constexpr auto kStartReorderThreshold = 30;
|
||||
constexpr auto kChatPreviewDelay = crl::time(1000);
|
||||
|
||||
int FixedOnTopDialogsCount(not_null<Dialogs::IndexedList*> list) {
|
||||
auto result = 0;
|
||||
|
@ -157,6 +159,7 @@ InnerWidget::InnerWidget(
|
|||
+ st::defaultDialogRow.padding.left())
|
||||
, _cancelSearchInChat(this, st::dialogsCancelSearchInPeer)
|
||||
, _cancelSearchFromUser(this, st::dialogsCancelSearchInPeer)
|
||||
, _chatPreviewTimer([=] { showChatPreview(); })
|
||||
, _childListShown(std::move(childListShown)) {
|
||||
setAttribute(Qt::WA_OpaquePaintEvent, true);
|
||||
|
||||
|
@ -651,6 +654,8 @@ void InnerWidget::paintEvent(QPaintEvent *e) {
|
|||
context.active = active;
|
||||
context.selected = _menuRow.key
|
||||
? (row->key() == _menuRow.key)
|
||||
: _chatPreviewKey
|
||||
? (row->key() == _chatPreviewKey)
|
||||
: selected;
|
||||
context.topicJumpSelected = selected
|
||||
&& _selectedTopicJump
|
||||
|
@ -1268,6 +1273,14 @@ void InnerWidget::mouseMoveEvent(QMouseEvent *e) {
|
|||
return;
|
||||
}
|
||||
selectByMouse(globalPosition);
|
||||
if (!isUserpicPress()) {
|
||||
cancelChatPreview();
|
||||
}
|
||||
}
|
||||
|
||||
void InnerWidget::cancelChatPreview() {
|
||||
_chatPreviewTimer.cancel();
|
||||
_chatPreviewWillBeFor = {};
|
||||
}
|
||||
|
||||
void InnerWidget::clearIrrelevantState() {
|
||||
|
@ -1490,11 +1503,15 @@ void InnerWidget::mousePressEvent(QMouseEvent *e) {
|
|||
row->repaint());
|
||||
}
|
||||
ClickHandler::pressed();
|
||||
if (anim::Disabled()
|
||||
if (pressShowsPreview()) {
|
||||
_chatPreviewWillBeFor = computeChosenRow().key;
|
||||
_chatPreviewTimer.callOnce(kChatPreviewDelay);
|
||||
} else if (anim::Disabled()
|
||||
&& (!_pressed || !_pressed->entry()->isPinnedDialog(_filterId))) {
|
||||
mousePressReleased(e->globalPos(), e->button(), e->modifiers());
|
||||
}
|
||||
}
|
||||
|
||||
const std::vector<Key> &InnerWidget::pinnedChatsOrder() const {
|
||||
const auto owner = &session().data();
|
||||
return _savedSublists
|
||||
|
@ -1513,6 +1530,7 @@ void InnerWidget::checkReorderPinnedStart(QPoint localPosition) {
|
|||
< style::ConvertScale(kStartReorderThreshold)) {
|
||||
return;
|
||||
}
|
||||
cancelChatPreview();
|
||||
_dragging = _pressed;
|
||||
if (updateReorderIndexGetCount() < 2) {
|
||||
_dragging = nullptr;
|
||||
|
@ -2288,6 +2306,33 @@ void InnerWidget::fillArchiveSearchMenu(not_null<Ui::PopupMenu*> menu) {
|
|||
});
|
||||
}
|
||||
|
||||
void InnerWidget::showChatPreview() {
|
||||
const auto key = base::take(_chatPreviewWillBeFor);
|
||||
cancelChatPreview();
|
||||
if (!pressShowsPreview() || key != computeChosenRow().key) {
|
||||
return;
|
||||
}
|
||||
ClickHandler::unpressed();
|
||||
mousePressReleased(QCursor::pos(), Qt::NoButton, Qt::NoModifier);
|
||||
|
||||
_chatPreviewKey = key;
|
||||
_menu = HistoryView::MakeChatPreview(this, key.entry());
|
||||
if (!_menu) {
|
||||
return;
|
||||
}
|
||||
QObject::connect(_menu.get(), &QObject::destroyed, [=] {
|
||||
if (_chatPreviewKey) {
|
||||
updateDialogRow(RowDescriptor(base::take(_chatPreviewKey), {}));
|
||||
}
|
||||
const auto globalPosition = QCursor::pos();
|
||||
if (rect().contains(mapFromGlobal(globalPosition))) {
|
||||
setMouseTracking(true);
|
||||
selectByMouse(globalPosition);
|
||||
}
|
||||
});
|
||||
_menu->popup(_lastMousePosition.value_or(QCursor::pos()));
|
||||
}
|
||||
|
||||
void InnerWidget::contextMenuEvent(QContextMenuEvent *e) {
|
||||
_menu = nullptr;
|
||||
|
||||
|
@ -2316,7 +2361,9 @@ void InnerWidget::contextMenuEvent(QContextMenuEvent *e) {
|
|||
}
|
||||
return RowDescriptor();
|
||||
}();
|
||||
if (!row.key) return;
|
||||
if (!row.key) {
|
||||
return;
|
||||
}
|
||||
|
||||
_menuRow = row;
|
||||
if (_pressButton != Qt::LeftButton) {
|
||||
|
@ -2555,6 +2602,12 @@ void InnerWidget::trackSearchResultsHistory(not_null<History*> history) {
|
|||
refresh();
|
||||
clearMouseSelection(true);
|
||||
}
|
||||
if (_chatPreviewWillBeFor.topic() == topic) {
|
||||
_chatPreviewWillBeFor = {};
|
||||
}
|
||||
if (_chatPreviewKey.topic() == topic) {
|
||||
_chatPreviewKey = {};
|
||||
}
|
||||
}, _searchResultsLifetime);
|
||||
}
|
||||
}
|
||||
|
@ -3499,6 +3552,23 @@ ChosenRow InnerWidget::computeChosenRow() const {
|
|||
return ChosenRow();
|
||||
}
|
||||
|
||||
bool InnerWidget::isUserpicPress() const {
|
||||
return (_lastRowLocalMouseX >= 0)
|
||||
&& (_lastRowLocalMouseX < _st->nameLeft)
|
||||
&& (width() > _narrowWidth);
|
||||
}
|
||||
|
||||
bool InnerWidget::pressShowsPreview() const {
|
||||
if (!isUserpicPress()) {
|
||||
return false;
|
||||
}
|
||||
const auto key = computeChosenRow().key;
|
||||
if (const auto history = key.history()) {
|
||||
return !history->peer->isForum();
|
||||
}
|
||||
return key.topic() != nullptr;;
|
||||
}
|
||||
|
||||
bool InnerWidget::chooseRow(
|
||||
Qt::KeyboardModifiers modifiers,
|
||||
MsgId pressedTopicRootId) {
|
||||
|
@ -3511,9 +3581,7 @@ bool InnerWidget::chooseRow(
|
|||
ChosenRow row,
|
||||
Qt::KeyboardModifiers modifiers) {
|
||||
row.newWindow = (modifiers & Qt::ControlModifier);
|
||||
row.userpicClick = (_lastRowLocalMouseX >= 0)
|
||||
&& (_lastRowLocalMouseX < _st->nameLeft)
|
||||
&& (width() > _narrowWidth);
|
||||
row.userpicClick = isUserpicPress();
|
||||
return row;
|
||||
};
|
||||
auto chosen = modifyChosenRow(computeChosenRow(), modifiers);
|
||||
|
|
|
@ -7,14 +7,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
#include "base/flags.h"
|
||||
#include "base/object_ptr.h"
|
||||
#include "base/timer.h"
|
||||
#include "dialogs/dialogs_key.h"
|
||||
#include "data/data_messages.h"
|
||||
#include "ui/dragging_scroll_manager.h"
|
||||
#include "ui/effects/animations.h"
|
||||
#include "ui/rp_widget.h"
|
||||
#include "ui/userpic_view.h"
|
||||
#include "base/flags.h"
|
||||
#include "base/object_ptr.h"
|
||||
|
||||
namespace style {
|
||||
struct DialogRow;
|
||||
|
@ -121,6 +122,10 @@ public:
|
|||
void refreshEmptyLabel();
|
||||
void resizeEmptyLabel();
|
||||
|
||||
[[nodiscard]] bool isUserpicPress() const;
|
||||
[[nodiscard]] bool pressShowsPreview() const;
|
||||
void cancelChatPreview();
|
||||
void showChatPreview();
|
||||
bool chooseRow(
|
||||
Qt::KeyboardModifiers modifiers = {},
|
||||
MsgId pressedTopicRootId = {});
|
||||
|
@ -514,6 +519,10 @@ private:
|
|||
rpl::event_stream<QString> _completeHashtagRequests;
|
||||
rpl::event_stream<> _refreshHashtagsRequests;
|
||||
|
||||
base::Timer _chatPreviewTimer;
|
||||
Key _chatPreviewWillBeFor;
|
||||
Key _chatPreviewKey;
|
||||
|
||||
rpl::variable<ChildListShown> _childListShown;
|
||||
float64 _narrowRatio = 0.;
|
||||
bool _geometryInited = false;
|
||||
|
|
113
Telegram/SourceFiles/history/view/history_view_chat_preview.cpp
Normal file
113
Telegram/SourceFiles/history/view/history_view_chat_preview.cpp
Normal file
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "history/view/history_view_chat_preview.h"
|
||||
|
||||
#include "data/data_peer.h"
|
||||
#include "history/history.h"
|
||||
#include "ui/chat/chat_theme.h"
|
||||
#include "ui/widgets/popup_menu.h"
|
||||
#include "ui/widgets/menu/menu_item_base.h"
|
||||
#include "window/themes/window_theme.h"
|
||||
#include "window/section_widget.h"
|
||||
#include "styles/style_chat.h"
|
||||
|
||||
namespace HistoryView {
|
||||
namespace {
|
||||
|
||||
class Item final : public Ui::Menu::ItemBase {
|
||||
public:
|
||||
Item(not_null<Ui::RpWidget*> parent, not_null<History*> history);
|
||||
|
||||
not_null<QAction*> action() const override;
|
||||
bool isEnabled() const override;
|
||||
|
||||
private:
|
||||
void setupBackground();
|
||||
|
||||
int contentHeight() const override;
|
||||
|
||||
void paintEvent(QPaintEvent *e) override;
|
||||
|
||||
const not_null<QAction*> _dummyAction;
|
||||
const std::shared_ptr<Ui::ChatTheme> _theme;
|
||||
|
||||
QImage _bg;
|
||||
|
||||
};
|
||||
|
||||
Item::Item(not_null<Ui::RpWidget*> parent, not_null<History*> history)
|
||||
: Ui::Menu::ItemBase(parent, st::previewMenu.menu)
|
||||
, _dummyAction(new QAction(parent))
|
||||
, _theme(Window::Theme::DefaultChatThemeOn(lifetime())) {
|
||||
setPointerCursor(false);
|
||||
setMinWidth(st::previewMenu.menu.widthMin);
|
||||
resize(minWidth(), contentHeight());
|
||||
setupBackground();
|
||||
}
|
||||
|
||||
not_null<QAction*> Item::action() const {
|
||||
return _dummyAction;
|
||||
}
|
||||
|
||||
bool Item::isEnabled() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
int Item::contentHeight() const {
|
||||
return st::previewMenu.maxHeight;
|
||||
}
|
||||
|
||||
void Item::setupBackground() {
|
||||
const auto ratio = style::DevicePixelRatio();
|
||||
_bg = QImage(
|
||||
size() * ratio,
|
||||
QImage::Format_ARGB32_Premultiplied);
|
||||
|
||||
const auto paint = [=] {
|
||||
auto p = QPainter(&_bg);
|
||||
Window::SectionWidget::PaintBackground(
|
||||
p,
|
||||
_theme.get(),
|
||||
QSize(width(), height() * 2),
|
||||
QRect(QPoint(), size()));
|
||||
};
|
||||
paint();
|
||||
_theme->repaintBackgroundRequests() | rpl::start_with_next([=] {
|
||||
paint();
|
||||
update();
|
||||
}, lifetime());
|
||||
}
|
||||
|
||||
void Item::paintEvent(QPaintEvent *e) {
|
||||
auto p = QPainter(this);
|
||||
p.drawImage(0, 0, _bg);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
base::unique_qptr<Ui::PopupMenu> MakeChatPreview(
|
||||
QWidget *parent,
|
||||
not_null<Dialogs::Entry*> entry) {
|
||||
if (const auto topic = entry->asTopic()) {
|
||||
return nullptr;
|
||||
}
|
||||
const auto history = entry->asHistory();
|
||||
if (!history || history->peer->isForum()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto result = base::make_unique_q<Ui::PopupMenu>(
|
||||
parent,
|
||||
st::previewMenu);
|
||||
|
||||
result->addAction(base::make_unique_q<Item>(result.get(), history));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace HistoryView
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "base/unique_qptr.h"
|
||||
|
||||
namespace Dialogs {
|
||||
class Entry;
|
||||
} // namespace Dialogs
|
||||
|
||||
namespace Ui {
|
||||
class PopupMenu;
|
||||
} // namespace Ui
|
||||
|
||||
namespace HistoryView {
|
||||
|
||||
[[nodiscard]] base::unique_qptr<Ui::PopupMenu> MakeChatPreview(
|
||||
QWidget *parent,
|
||||
not_null<Dialogs::Entry*> entry);
|
||||
|
||||
} // namespace HistoryView
|
|
@ -1076,3 +1076,12 @@ liveLocationLongInIconSelected: icon {{ "chat/live_location_long", msgInServiceF
|
|||
liveLocationLongOutIcon: icon {{ "chat/live_location_long", msgOutServiceFg }};
|
||||
liveLocationLongOutIconSelected: icon {{ "chat/live_location_long", msgOutServiceFgSelected }};
|
||||
liveLocationRemainingSize: 28px;
|
||||
|
||||
previewMenu: PopupMenu(defaultPopupMenu) {
|
||||
scrollPadding: margins(0px, 0px, 0px, 0px);
|
||||
menu: Menu(defaultMenu) {
|
||||
widthMin: 380px;
|
||||
widthMax: 380px;
|
||||
}
|
||||
maxHeight: 420px;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue