mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-14 21:27:07 +02:00
Add jump-to-end button to chat preview.
This commit is contained in:
parent
40cf96202d
commit
6fce718252
4 changed files with 130 additions and 22 deletions
|
@ -189,7 +189,8 @@ rpl::producer<MessagesSlice> HistoryMessagesViewer(
|
|||
};
|
||||
const auto messageId = (aroundId.fullId.msg == ShowAtUnreadMsgId)
|
||||
? computeUnreadAroundId()
|
||||
: (aroundId.fullId.msg == ShowAtTheEndMsgId)
|
||||
: ((aroundId.fullId.msg == ShowAtTheEndMsgId)
|
||||
|| (aroundId == MaxMessagePosition))
|
||||
? (ServerMaxMsgId - 1)
|
||||
: (aroundId.fullId.peer == history->peer->id)
|
||||
? aroundId.fullId.msg
|
||||
|
|
|
@ -19,6 +19,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "data/data_session.h"
|
||||
#include "data/data_thread.h"
|
||||
#include "history/view/reactions/history_view_reactions_button.h"
|
||||
#include "history/view/history_view_corner_buttons.h"
|
||||
#include "history/view/history_view_list_widget.h"
|
||||
#include "history/history.h"
|
||||
#include "history/history_item.h"
|
||||
|
@ -52,7 +53,8 @@ namespace {
|
|||
|
||||
class Item final
|
||||
: public Ui::Menu::ItemBase
|
||||
, private HistoryView::ListDelegate {
|
||||
, private ListDelegate
|
||||
, private CornerButtonsDelegate {
|
||||
public:
|
||||
Item(not_null<Ui::RpWidget*> parent, not_null<Data::Thread*> thread);
|
||||
|
||||
|
@ -73,6 +75,7 @@ private:
|
|||
void setupHistory();
|
||||
void updateInnerVisibleArea();
|
||||
|
||||
// ListDelegate delegate.
|
||||
Context listContext() override;
|
||||
bool listScrollTo(int top, bool syntetic = true) override;
|
||||
void listCancelRequest() override;
|
||||
|
@ -164,6 +167,16 @@ private:
|
|||
std::unique_ptr<QMimeData> data,
|
||||
Fn<void()> finished) override;
|
||||
|
||||
// CornerButtonsDelegate delegate.
|
||||
void cornerButtonsShowAtPosition(
|
||||
Data::MessagePosition position) override;
|
||||
Data::Thread *cornerButtonsThread() override;
|
||||
FullMsgId cornerButtonsCurrentId() override;
|
||||
bool cornerButtonsIgnoreVisibility() override;
|
||||
std::optional<bool> cornerButtonsDownShown() override;
|
||||
bool cornerButtonsUnreadMayBeShown() override;
|
||||
bool cornerButtonsHas(CornerButtonType type) override;
|
||||
|
||||
const not_null<QAction*> _dummyAction;
|
||||
const not_null<Main::Session*> _session;
|
||||
const not_null<Data::Thread*> _thread;
|
||||
|
@ -176,7 +189,8 @@ private:
|
|||
const std::unique_ptr<Ui::ElasticScroll> _scroll;
|
||||
const std::unique_ptr<Ui::FlatButton> _markRead;
|
||||
|
||||
QPointer<HistoryView::ListWidget> _inner;
|
||||
QPointer<ListWidget> _inner;
|
||||
std::unique_ptr<CornerButtons> _cornerButtons;
|
||||
rpl::event_stream<ChatPreviewAction> _actions;
|
||||
|
||||
QImage _bg;
|
||||
|
@ -446,11 +460,16 @@ void Item::setupHistory() {
|
|||
this,
|
||||
_session,
|
||||
static_cast<ListDelegate*>(this)));
|
||||
_cornerButtons = std::make_unique<CornerButtons>(
|
||||
_scroll.get(),
|
||||
_chatStyle.get(),
|
||||
static_cast<CornerButtonsDelegate*>(this));
|
||||
|
||||
_markRead->shownValue() | rpl::start_with_next([=](bool shown) {
|
||||
const auto top = _top->height();
|
||||
const auto bottom = shown ? _markRead->height() : 0;
|
||||
_scroll->setGeometry(rect().marginsRemoved({ 0, top, 0, bottom }));
|
||||
_cornerButtons->updatePositions();
|
||||
}, _markRead->lifetime());
|
||||
|
||||
_scroll->scrolls(
|
||||
|
@ -495,6 +514,7 @@ void Item::paintEvent(QPaintEvent *e) {
|
|||
void Item::updateInnerVisibleArea() {
|
||||
const auto scrollTop = _scroll->scrollTop();
|
||||
_inner->setVisibleTopBottom(scrollTop, scrollTop + _scroll->height());
|
||||
_cornerButtons->updateJumpDownVisibility();
|
||||
}
|
||||
|
||||
Context Item::listContext() {
|
||||
|
@ -592,18 +612,28 @@ MessagesBarData Item::listMessagesBar(
|
|||
return {};
|
||||
}
|
||||
|
||||
auto skipped = false;
|
||||
const auto hidden = _replies && (repliesTill < 2);
|
||||
for (auto i = 0, count = int(elements.size()); i != count; ++i) {
|
||||
const auto item = elements[i]->data();
|
||||
if (!item->isRegular()
|
||||
|| item->out()
|
||||
|| (_replies && !item->replyToId())) {
|
||||
if (!item->isRegular() || (_replies && !item->replyToId())) {
|
||||
continue;
|
||||
}
|
||||
const auto inHistory = (item->history() == _history);
|
||||
if ((_replies && item->id > repliesTill)
|
||||
const auto unread = (_replies && item->id > repliesTill)
|
||||
|| (migratedTill && (inHistory || item->id > migratedTill))
|
||||
|| (historyTill && inHistory && item->id > historyTill)) {
|
||||
|| (historyTill && inHistory && item->id > historyTill);
|
||||
if (!unread) {
|
||||
skipped = true;
|
||||
}
|
||||
if (item->out()) {
|
||||
continue;
|
||||
}
|
||||
if (unread) {
|
||||
if (!skipped) {
|
||||
// Don't show jumping unread bar if scrolling up from bottom.
|
||||
return {};
|
||||
}
|
||||
return {
|
||||
.bar = {
|
||||
.element = elements[i],
|
||||
|
@ -800,6 +830,46 @@ void Item::listLaunchDrag(
|
|||
Fn<void()> finished) {
|
||||
}
|
||||
|
||||
void Item::cornerButtonsShowAtPosition(Data::MessagePosition position) {
|
||||
if (position == Data::UnreadMessagePosition) {
|
||||
position = Data::MaxMessagePosition;
|
||||
}
|
||||
_inner->showAtPosition(
|
||||
position,
|
||||
{},
|
||||
_cornerButtons->doneJumpFrom(position.fullId, {}, true));
|
||||
}
|
||||
|
||||
Data::Thread *Item::cornerButtonsThread() {
|
||||
return _thread;
|
||||
}
|
||||
|
||||
FullMsgId Item::cornerButtonsCurrentId() {
|
||||
return {};
|
||||
}
|
||||
|
||||
bool Item::cornerButtonsIgnoreVisibility() {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::optional<bool> Item::cornerButtonsDownShown() {
|
||||
const auto top = _scroll->scrollTop() + st::historyToDownShownAfter;
|
||||
if (top < _scroll->scrollTopMax()) {
|
||||
return true;
|
||||
} else if (_inner->loadedAtBottomKnown()) {
|
||||
return !_inner->loadedAtBottom();
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
bool Item::cornerButtonsUnreadMayBeShown() {
|
||||
return _inner->loadedAtBottomKnown();
|
||||
}
|
||||
|
||||
bool Item::cornerButtonsHas(CornerButtonType type) {
|
||||
return (type == CornerButtonType::Down);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
ChatPreview MakeChatPreview(
|
||||
|
|
|
@ -7,9 +7,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
*/
|
||||
#include "history/view/history_view_corner_buttons.h"
|
||||
|
||||
#include "ui/widgets/scroll_area.h"
|
||||
#include "ui/chat/chat_style.h"
|
||||
#include "ui/controls/jump_down_button.h"
|
||||
#include "ui/widgets/elastic_scroll.h"
|
||||
#include "ui/widgets/scroll_area.h"
|
||||
#include "base/qt/qt_key_modifiers.h"
|
||||
#include "history/history.h"
|
||||
#include "history/history_item.h"
|
||||
|
@ -33,17 +34,41 @@ CornerButtons::CornerButtons(
|
|||
not_null<Ui::ScrollArea*> parent,
|
||||
not_null<const Ui::ChatStyle*> st,
|
||||
not_null<CornerButtonsDelegate*> delegate)
|
||||
: _scroll(parent)
|
||||
: CornerButtons(
|
||||
parent,
|
||||
[=](QEvent *e) { return parent->viewportEvent(e); },
|
||||
st,
|
||||
delegate) {
|
||||
}
|
||||
|
||||
CornerButtons::CornerButtons(
|
||||
not_null<Ui::ElasticScroll*> parent,
|
||||
not_null<const Ui::ChatStyle*> st,
|
||||
not_null<CornerButtonsDelegate*> delegate)
|
||||
: CornerButtons(
|
||||
parent,
|
||||
[=](QEvent *e) { return parent->viewportEvent(e); },
|
||||
st,
|
||||
delegate) {
|
||||
}
|
||||
|
||||
CornerButtons::CornerButtons(
|
||||
not_null<QWidget*> parent,
|
||||
Fn<bool(QEvent*)> scrollViewportEvent,
|
||||
not_null<const Ui::ChatStyle*> st,
|
||||
not_null<CornerButtonsDelegate*> delegate)
|
||||
: _parent(parent)
|
||||
, _scrollViewportEvent(std::move(scrollViewportEvent))
|
||||
, _delegate(delegate)
|
||||
, _down(
|
||||
parent,
|
||||
st->value(parent->lifetime(), st::historyToDown))
|
||||
st->value(_stLifetime, st::historyToDown))
|
||||
, _mentions(
|
||||
parent,
|
||||
st->value(parent->lifetime(), st::historyUnreadMentions))
|
||||
st->value(_stLifetime, st::historyUnreadMentions))
|
||||
, _reactions(
|
||||
parent,
|
||||
st->value(parent->lifetime(), st::historyUnreadReactions)) {
|
||||
st->value(_stLifetime, st::historyUnreadReactions)) {
|
||||
_down.widget->addClickHandler([=] { downClick(); });
|
||||
_mentions.widget->addClickHandler([=] { mentionsClick(); });
|
||||
_reactions.widget->addClickHandler([=] { reactionsClick(); });
|
||||
|
@ -68,7 +93,7 @@ bool CornerButtons::eventFilter(QObject *o, QEvent *e) {
|
|||
&& (o == _down.widget
|
||||
|| o == _mentions.widget
|
||||
|| o == _reactions.widget)) {
|
||||
return _scroll->viewportEvent(e);
|
||||
return _scrollViewportEvent(e);
|
||||
}
|
||||
return QObject::eventFilter(o, e);
|
||||
}
|
||||
|
@ -200,9 +225,7 @@ void CornerButtons::showAt(MsgId id) {
|
|||
}
|
||||
}
|
||||
|
||||
void CornerButtons::updateVisibility(
|
||||
CornerButtonType type,
|
||||
bool shown) {
|
||||
void CornerButtons::updateVisibility(Type type, bool shown) {
|
||||
auto &button = buttonByType(type);
|
||||
if (button.shown != shown) {
|
||||
button.shown = shown;
|
||||
|
@ -291,7 +314,7 @@ void CornerButtons::updatePositions() {
|
|||
historyDownShown);
|
||||
_down.widget->moveToRight(
|
||||
st::historyToDownPosition.x(),
|
||||
_scroll->height() - top);
|
||||
_parent->height() - top);
|
||||
}
|
||||
{
|
||||
const auto right = anim::interpolate(
|
||||
|
@ -302,7 +325,7 @@ void CornerButtons::updatePositions() {
|
|||
0,
|
||||
_down.widget->height() + skip,
|
||||
historyDownShown);
|
||||
const auto top = _scroll->height()
|
||||
const auto top = _parent->height()
|
||||
- _mentions.widget->height()
|
||||
- st::historyToDownPosition.y()
|
||||
- shift;
|
||||
|
@ -321,7 +344,7 @@ void CornerButtons::updatePositions() {
|
|||
0,
|
||||
_mentions.widget->height() + skip,
|
||||
unreadMentionsShown);
|
||||
const auto top = _scroll->height()
|
||||
const auto top = _parent->height()
|
||||
- _reactions.widget->height()
|
||||
- st::historyToDownPosition.y()
|
||||
- shift;
|
||||
|
@ -355,7 +378,7 @@ Fn<void(bool found)> CornerButtons::doneJumpFrom(
|
|||
}
|
||||
if (!found && !ignoreMessageNotFound) {
|
||||
Ui::Toast::Show(
|
||||
_scroll.get(),
|
||||
_parent.get(),
|
||||
tr::lng_message_not_found(tr::now));
|
||||
}
|
||||
};
|
||||
|
|
|
@ -17,6 +17,7 @@ struct FullMsgId;
|
|||
namespace Ui {
|
||||
class ChatStyle;
|
||||
class ScrollArea;
|
||||
class ElasticScroll;
|
||||
class JumpDownButton;
|
||||
} // namespace Ui
|
||||
|
||||
|
@ -61,6 +62,10 @@ public:
|
|||
not_null<Ui::ScrollArea*> parent,
|
||||
not_null<const Ui::ChatStyle*> st,
|
||||
not_null<CornerButtonsDelegate*> delegate);
|
||||
CornerButtons(
|
||||
not_null<Ui::ElasticScroll*> parent,
|
||||
not_null<const Ui::ChatStyle*> st,
|
||||
not_null<CornerButtonsDelegate*> delegate);
|
||||
|
||||
using Type = CornerButtonType;
|
||||
|
||||
|
@ -91,6 +96,12 @@ public:
|
|||
bool ignoreMessageNotFound = false);
|
||||
|
||||
private:
|
||||
CornerButtons(
|
||||
not_null<QWidget*> parent,
|
||||
Fn<bool(QEvent*)> scrollViewportEvent,
|
||||
not_null<const Ui::ChatStyle*> st,
|
||||
not_null<CornerButtonsDelegate*> delegate);
|
||||
|
||||
bool eventFilter(QObject *o, QEvent *e) override;
|
||||
|
||||
void computeCurrentReplyReturn();
|
||||
|
@ -99,9 +110,12 @@ private:
|
|||
[[nodiscard]] History *lookupHistory() const;
|
||||
void showAt(MsgId id);
|
||||
|
||||
const not_null<Ui::ScrollArea*> _scroll;
|
||||
const not_null<QWidget*> _parent;
|
||||
const Fn<bool(QEvent*)> _scrollViewportEvent;
|
||||
const not_null<CornerButtonsDelegate*> _delegate;
|
||||
|
||||
rpl::lifetime _stLifetime;
|
||||
|
||||
CornerButton _down;
|
||||
CornerButton _mentions;
|
||||
CornerButton _reactions;
|
||||
|
|
Loading…
Add table
Reference in a new issue