Show "View as Messages" preview by Alt+Click.

This commit is contained in:
John Preston 2024-05-31 14:39:35 +04:00
parent ad342a5324
commit 4e8895ddd9
9 changed files with 80 additions and 29 deletions

View File

@ -1495,6 +1495,8 @@ RowDescriptor InnerWidget::computeChatPreviewRow() const {
: 0;
if (const auto topic = peer->forumTopicFor(topicId)) {
return { topic, FullMsgId() };
} else if (peer->isForum() && !result.key.topic()) {
return {};
}
}
return { result.key, result.message.fullId };

View File

@ -22,6 +22,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/view/history_view_list_widget.h"
#include "history/history.h"
#include "history/history_item.h"
#include "history/history_item_components.h"
#include "info/profile/info_profile_cover.h"
#include "info/profile/info_profile_values.h"
#include "lang/lang_keys.h"
@ -369,7 +370,10 @@ void Item::setupMarkRead() {
) | rpl::start_with_next([=] {
const auto state = _thread->chatListBadgesState();
const auto unread = (state.unreadCounter || state.unread);
if (_thread->asTopic() && !unread) {
const auto hidden = _thread->asTopic()
? (!unread)
: _thread->peer()->isForum();
if (hidden) {
_markRead->hide();
return;
}
@ -595,7 +599,11 @@ void Item::listUpdateDateLink(
}
bool Item::listElementHideReply(not_null<const Element*> view) {
return false;
if (!view->isTopicRootReply()) {
return false;
}
const auto reply = view->data()->Get<HistoryMessageReply>();
return reply && !reply->fields().manualQuote;
}
bool Item::listElementShownUnread(not_null<const Element*> view) {
@ -769,10 +777,6 @@ ChatPreview MakeChatPreview(
const auto thread = entry->asThread();
if (!thread) {
return {};
} else if (const auto history = entry->asHistory()) {
if (history->peer->isForum()) {
return {};
}
}
auto result = ChatPreview{

View File

@ -1042,7 +1042,9 @@ QSize Message::performCountOptimalSize() {
void Message::refreshTopicButton() {
const auto item = data();
if (isAttachedToPrevious() || context() != Context::History) {
if (isAttachedToPrevious()
|| (context() != Context::History
&& context() != Context::ChatPreview)) {
_topicButton = nullptr;
} else if (const auto topic = item->topic()) {
if (!_topicButton) {

View File

@ -33,16 +33,21 @@ ChatPreviewManager::ChatPreviewManager(
bool ChatPreviewManager::show(
Dialogs::RowDescriptor row,
Fn<void(bool shown)> callback) {
Fn<void(bool shown)> callback,
QPointer<QWidget> parentOverride) {
cancelScheduled();
_topicLifetime.destroy();
if (const auto topic = row.key.topic()) {
_topicLifetime = topic->destroyed() | rpl::start_with_next([=] {
_menu = nullptr;
});
} else if (!row.key) {
return false;
}
const auto parent = _controller->content();
const auto parent = parentOverride
? parentOverride
: _controller->content();
auto preview = HistoryView::MakeChatPreview(parent, row.key.entry());
if (!preview.menu) {
return false;
@ -81,10 +86,14 @@ bool ChatPreviewManager::show(
}, _menu->lifetime());
QObject::connect(_menu.get(), &QObject::destroyed, [=] {
_topicLifetime.destroy();
callback(false);
if (callback) {
callback(false);
}
});
callback(true);
if (callback) {
callback(true);
}
_menu->popup(QCursor::pos());
return true;
@ -92,7 +101,8 @@ bool ChatPreviewManager::show(
bool ChatPreviewManager::schedule(
Dialogs::RowDescriptor row,
Fn<void(bool shown)> callback) {
Fn<void(bool shown)> callback,
QPointer<QWidget> parentOverride) {
cancelScheduled();
_topicLifetime.destroy();
if (const auto topic = row.key.topic()) {
@ -100,15 +110,12 @@ bool ChatPreviewManager::schedule(
cancelScheduled();
_menu = nullptr;
});
} else if (const auto history = row.key.history()) {
if (history->peer->isForum()) {
return false;
}
} else {
return false;
}
_scheduled = row;
_scheduled = std::move(row);
_scheduledCallback = std::move(callback);
_scheduledParentOverride = std::move(parentOverride);
_timer.callOnce(kChatPreviewDelay);
return true;
}

View File

@ -25,10 +25,12 @@ public:
bool show(
Dialogs::RowDescriptor row,
Fn<void(bool shown)> callback = nullptr);
Fn<void(bool shown)> callback = nullptr,
QPointer<QWidget> parentOverride = nullptr);
bool schedule(
Dialogs::RowDescriptor row,
Fn<void(bool shown)> callback = nullptr);
Fn<void(bool shown)> callback = nullptr,
QPointer<QWidget> parentOverride = nullptr);
void cancelScheduled();
private:
@ -37,6 +39,7 @@ private:
const not_null<SessionController*> _controller;
Dialogs::RowDescriptor _scheduled;
Fn<void(bool)> _scheduledCallback;
QPointer<QWidget> _scheduledParentOverride;
base::Timer _timer;
rpl::lifetime _topicLifetime;

View File

@ -20,6 +20,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/random.h"
#include "base/options.h"
#include "base/unixtime.h"
#include "base/qt/qt_key_modifiers.h"
#include "boxes/delete_messages_box.h"
#include "boxes/max_invite_box.h"
#include "boxes/moderate_messages_box.h"
@ -94,7 +95,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "styles/style_menu_icons.h"
#include <QAction>
#include <QtGui/QGuiApplication>
#include <QtWidgets/QApplication>
namespace Window {
namespace {
@ -1239,12 +1240,36 @@ void Filler::addViewAsMessages() {
}
const auto peer = _peer;
const auto controller = _controller;
_addAction(tr::lng_forum_view_as_messages(tr::now), [=] {
const auto parentHideRequests = std::make_shared<rpl::event_stream<>>();
const auto filterOutChatPreview = [=] {
if (base::IsAltPressed()) {
const auto callback = [=](bool shown) {
if (!shown) {
parentHideRequests->fire({});
}
};
controller->showChatPreview({
peer->owner().history(peer),
FullMsgId(),
}, callback, QApplication::activePopupWidget());
return true;
}
return false;
};
const auto open = [=] {
if (const auto forum = peer->forum()) {
peer->owner().saveViewAsMessages(forum, true);
}
controller->showPeerHistory(peer->id);
}, &st::menuIconAsMessages);
};
auto to_instant = rpl::map_to(anim::type::instant);
_addAction({
.text = tr::lng_forum_view_as_messages(tr::now),
.handler = open,
.icon = &st::menuIconAsMessages,
.triggerFilter = filterOutChatPreview,
.hideRequests = parentHideRequests->events() | to_instant
});
}
void Filler::addViewAsTopics() {

View File

@ -2978,16 +2978,22 @@ QString SessionController::premiumRef() const {
bool SessionController::showChatPreview(
Dialogs::RowDescriptor row,
Fn<void(bool shown)> callback) {
return _chatPreviewManager->show(std::move(row), std::move(callback));
Fn<void(bool shown)> callback,
QPointer<QWidget> parentOverride) {
return _chatPreviewManager->show(
std::move(row),
std::move(callback),
std::move(parentOverride));
}
bool SessionController::scheduleChatPreview(
Dialogs::RowDescriptor row,
Fn<void(bool shown)> callback) {
Fn<void(bool shown)> callback,
QPointer<QWidget> parentOverride) {
return _chatPreviewManager->schedule(
std::move(row),
std::move(callback));
std::move(callback),
std::move(parentOverride));
}
void SessionController::cancelScheduledPreview() {

View File

@ -603,10 +603,12 @@ public:
bool showChatPreview(
Dialogs::RowDescriptor row,
Fn<void(bool shown)> callback = nullptr);
Fn<void(bool shown)> callback = nullptr,
QPointer<QWidget> parentOverride = nullptr);
bool scheduleChatPreview(
Dialogs::RowDescriptor row,
Fn<void(bool shown)> callback = nullptr);
Fn<void(bool shown)> callback = nullptr,
QPointer<QWidget> parentOverride = nullptr);
void cancelScheduledPreview();
[[nodiscard]] bool contentOverlapped(QWidget *w, QPaintEvent *e) const;

@ -1 +1 @@
Subproject commit 33aac93b160d4cd30119c8859de722e28512902b
Subproject commit d0514b2b022043b3777b06d6068232aa4cda7e80