Jump to date by date click in feed.

This commit is contained in:
John Preston 2018-02-22 02:59:56 +03:00
parent f066f3f139
commit a1be63f890
6 changed files with 115 additions and 23 deletions

View File

@ -2756,6 +2756,7 @@ void ApiWrap::requestMessageAfterDate(
void ApiWrap::jumpToFeedDate(not_null<Data::Feed*> feed, const QDate &date) {
requestMessageAfterDate(feed, date, [=](Data::MessagePosition result) {
Ui::hideLayer();
App::wnd()->controller()->showSection(
HistoryFeed::Memento(feed, result));
});

View File

@ -437,6 +437,15 @@ void Widget::listContentRefreshed() {
}
}
ClickHandlerPtr Widget::listDateLink(not_null<Element*> view) {
if (!_dateLink) {
_dateLink = std::make_shared<Window::DateClickHandler>(_feed, view->dateTime().date());
} else {
_dateLink->setDate(view->dateTime().date());
}
return _dateLink;
}
std::unique_ptr<Window::SectionMemento> Widget::createMemento() {
auto result = std::make_unique<Memento>(_feed);
saveState(result.get());

View File

@ -27,6 +27,10 @@ class TopBarWidget;
class Element;
} // namespace HistoryView
namespace Window {
class DateClickHandler;
} // namespace Window
namespace HistoryFeed {
class Memento;
@ -85,6 +89,7 @@ public:
base::optional<int> listUnreadBarView(
const std::vector<not_null<Element*>> &elements) override;
void listContentRefreshed() override;
ClickHandlerPtr listDateLink(not_null<Element*> view) override;
protected:
void resizeEvent(QResizeEvent *e) override;
@ -136,7 +141,7 @@ private:
Animation _scrollDownShown;
bool _scrollDownIsShown = false;
object_ptr<Ui::HistoryDownButton> _scrollDown;
std::shared_ptr<Window::DateClickHandler> _dateLink;
};

View File

@ -621,7 +621,9 @@ void ListWidget::scrollDateCheck() {
void ListWidget::scrollDateHideByTimer() {
_scrollDateHideTimer.cancel();
scrollDateHide();
if (!_scrollDateLink || ClickHandler::getPressed() != _scrollDateLink) {
scrollDateHide();
}
}
void ListWidget::scrollDateHide() {
@ -630,6 +632,15 @@ void ListWidget::scrollDateHide() {
}
}
void ListWidget::keepScrollDateForNow() {
if (!_scrollDateShown
&& _scrollDateLastItem
&& _scrollDateOpacity.animating()) {
toggleScrollDateShown();
}
_scrollDateHideTimer.callOnce(kScrollDateHideTimeout);
}
void ListWidget::toggleScrollDateShown() {
_scrollDateShown = !_scrollDateShown;
auto from = _scrollDateShown ? 0. : 1.;
@ -1602,10 +1613,20 @@ void ListWidget::mousePressEvent(QMouseEvent *e) {
}
void ListWidget::mouseMoveEvent(QMouseEvent *e) {
static auto lastGlobalPosition = e->globalPos();
auto reallyMoved = (lastGlobalPosition != e->globalPos());
auto buttonsPressed = (e->buttons() & (Qt::LeftButton | Qt::MiddleButton));
if (!buttonsPressed && _mouseAction != MouseAction::None) {
mouseReleaseEvent(e);
}
if (reallyMoved) {
lastGlobalPosition = e->globalPos();
if (!buttonsPressed
|| (_scrollDateLink
&& ClickHandler::getPressed() == _scrollDateLink)) {
keepScrollDateForNow();
}
}
mouseActionUpdate(e->globalPos());
}
@ -2047,34 +2068,87 @@ void ListWidget::mouseActionUpdate() {
} else {
inTextSelection = false;
}
// #TODO enumerate dates like HistoryInner
dragState = view->textState(itemPoint, request);
_overItemExact = App::histItemById(dragState.itemId);
lnkhost = view;
if (!dragState.link
&& itemPoint.x() >= st::historyPhotoLeft
&& itemPoint.x() < st::historyPhotoLeft + st::msgPhotoSize) {
if (view->hasFromPhoto()) {
enumerateUserpics([&](not_null<Element*> view, int userpicTop) {
// stop enumeration if the userpic is below our point
if (userpicTop > point.y()) {
return false;
const auto dateHeight = st::msgServicePadding.bottom()
+ st::msgServiceFont->height
+ st::msgServicePadding.top();
const auto scrollDateOpacity = _scrollDateOpacity.current(_scrollDateShown ? 1. : 0.);
enumerateDates([&](not_null<Element*> view, int itemtop, int dateTop) {
// stop enumeration if the date is above our point
if (dateTop + dateHeight <= point.y()) {
return false;
}
const auto displayDate = view->displayDate();
auto dateInPlace = displayDate;
if (dateInPlace) {
const auto correctDateTop = itemtop + st::msgServiceMargin.top();
dateInPlace = (dateTop < correctDateTop + dateHeight);
}
// stop enumeration if we've found a date under the cursor
if (dateTop <= point.y()) {
auto opacity = (dateInPlace/* || noFloatingDate*/) ? 1. : scrollDateOpacity;
if (opacity > 0.) {
const auto item = view->data();
auto dateWidth = 0;
if (const auto date = view->Get<HistoryView::DateBadge>()) {
dateWidth = date->width;
} else {
dateWidth = st::msgServiceFont->width(langDayOfMonthFull(view->dateTime().date()));
}
dateWidth += st::msgServicePadding.left() + st::msgServicePadding.right();
auto dateLeft = st::msgServiceMargin.left();
auto maxwidth = view->width();
if (Adaptive::ChatWide()) {
maxwidth = qMin(maxwidth, int32(st::msgMaxWidth + 2 * st::msgPhotoSkip + 2 * st::msgMargin.left()));
}
auto widthForDate = maxwidth - st::msgServiceMargin.left() - st::msgServiceMargin.left();
// stop enumeration if we've found a userpic under the cursor
if (point.y() >= userpicTop && point.y() < userpicTop + st::msgPhotoSize) {
const auto message = view->data()->toHistoryMessage();
Assert(message != nullptr);
dateLeft += (widthForDate - dateWidth) / 2;
if (point.x() >= dateLeft && point.x() < dateLeft + dateWidth) {
_scrollDateLink = _delegate->listDateLink(view);
dragState = TextState(
nullptr,
message->displayFrom()->openLink());
_scrollDateLink);
_overItemExact = App::histItemById(dragState.itemId);
lnkhost = view;
return false;
}
return true;
});
}
return false;
}
return true;
});
if (!dragState.link) {
dragState = view->textState(itemPoint, request);
_overItemExact = App::histItemById(dragState.itemId);
lnkhost = view;
if (!dragState.link
&& itemPoint.x() >= st::historyPhotoLeft
&& itemPoint.x() < st::historyPhotoLeft + st::msgPhotoSize) {
if (view->hasFromPhoto()) {
enumerateUserpics([&](not_null<Element*> view, int userpicTop) {
// stop enumeration if the userpic is below our point
if (userpicTop > point.y()) {
return false;
}
// stop enumeration if we've found a userpic under the cursor
if (point.y() >= userpicTop && point.y() < userpicTop + st::msgPhotoSize) {
const auto message = view->data()->toHistoryMessage();
Assert(message != nullptr);
dragState = TextState(
nullptr,
message->displayFrom()->openLink());
_overItemExact = App::histItemById(dragState.itemId);
lnkhost = view;
return false;
}
return true;
});
}
}
}
}

View File

@ -65,6 +65,7 @@ public:
virtual base::optional<int> listUnreadBarView(
const std::vector<not_null<Element*>> &elements) = 0;
virtual void listContentRefreshed() = 0;
virtual ClickHandlerPtr listDateLink(not_null<Element*> view) = 0;
};
@ -302,6 +303,7 @@ private:
void scrollDateHide();
void scrollDateCheck();
void scrollDateHideByTimer();
void keepScrollDateForNow();
void trySwitchToWordSelection();
void switchToWordSelection();
@ -440,6 +442,7 @@ private:
base::Timer _scrollDateHideTimer;
Element *_scrollDateLastItem = nullptr;
int _scrollDateLastItemTop = 0;
ClickHandlerPtr _scrollDateLink;
SingleQueuedInvokation _applyUpdatedScrollState;
Element *_unreadBarElement = nullptr;

View File

@ -337,7 +337,7 @@ void Controller::showJumpToDate(Dialogs::Key chat, QDate requestedDate) {
return history->chatsListDate().date();
}
} else if (const auto feed = chat.feed()) {
/*if (chatScrollPosition(feed)) {
/*if (chatScrollPosition(feed)) { // #TODO feeds save position
} else */if (!feed->chatsListDate().isNull()) {
return feed->chatsListDate().date();