Add search from group member button to dialogs.

This commit is contained in:
John Preston 2017-08-01 14:43:50 +03:00
parent 6f27e310ae
commit 91fda6b654
14 changed files with 124 additions and 100 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 209 B

After

Width:  |  Height:  |  Size: 173 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 275 B

After

Width:  |  Height:  |  Size: 255 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 343 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 660 B

View File

@ -1650,4 +1650,46 @@ void ApiWrap::applyUpdateNoPtsCheck(const MTPUpdate &update) {
}
}
void ApiWrap::jumpToDate(gsl::not_null<PeerData*> peer, const QDate &date) {
// API returns a message with date <= offset_date.
// So we request a message with offset_date = desired_date - 1 and add_offset = -1.
// This should give us the first message with date >= desired_date.
auto offset_date = static_cast<int>(QDateTime(date).toTime_t()) - 1;
auto add_offset = -1;
auto limit = 1;
request(MTPmessages_GetHistory(peer->input, MTP_int(0), MTP_int(offset_date), MTP_int(add_offset), MTP_int(limit), MTP_int(0), MTP_int(0))).done([peer](const MTPmessages_Messages &result) {
auto getMessagesList = [&result, peer]() -> const QVector<MTPMessage>* {
auto handleMessages = [](auto &messages) {
App::feedUsers(messages.vusers);
App::feedChats(messages.vchats);
return &messages.vmessages.v;
};
switch (result.type()) {
case mtpc_messages_messages: return handleMessages(result.c_messages_messages());
case mtpc_messages_messagesSlice: return handleMessages(result.c_messages_messagesSlice());
case mtpc_messages_channelMessages: {
auto &messages = result.c_messages_channelMessages();
if (peer && peer->isChannel()) {
peer->asChannel()->ptsReceived(messages.vpts.v);
} else {
LOG(("API Error: received messages.channelMessages when no channel was passed! (MainWidget::showJumpToDate)"));
}
return handleMessages(messages);
} break;
}
return nullptr;
};
if (auto list = getMessagesList()) {
App::feedMsgs(*list, NewMessageExisting);
for (auto &message : *list) {
auto id = idFromMessage(message);
Ui::showPeerHistory(peer, id);
return;
}
}
Ui::showPeerHistory(peer, ShowAtUnreadMsgId);
}).send();
}
ApiWrap::~ApiWrap() = default;

View File

@ -94,6 +94,8 @@ public:
void applyUpdatesNoPtsCheck(const MTPUpdates &updates);
void applyUpdateNoPtsCheck(const MTPUpdate &update);
void jumpToDate(gsl::not_null<PeerData*> peer, const QDate &date);
~ApiWrap();
private:

View File

@ -100,12 +100,17 @@ dialogsLock: IconButton(dialogsMenuToggle) {
dialogsUnlockIcon: icon {{ "dialogs_unlock", dialogsMenuIconFg }};
dialogsUnlockIconOver: icon {{ "dialogs_unlock", dialogsMenuIconFgOver }};
dialogsCalendar: IconButton {
width: 32px;
width: 29px;
height: 32px;
icon: icon {{ "dialogs_calendar", dialogsMenuIconFg }};
iconOver: icon {{ "dialogs_calendar", dialogsMenuIconFgOver }};
iconPosition: point(3px, 3px);
iconPosition: point(0px, 5px);
}
dialogsSearchFrom: IconButton(dialogsCalendar) {
width: 26px;
icon: icon {{ "dialogs_search_from", dialogsMenuIconFg }};
iconOver: icon {{ "dialogs_search_from", dialogsMenuIconFgOver }};
}
dialogsFilter: FlatInput(defaultFlatInput) {

View File

@ -2329,6 +2329,7 @@ void DialogsWidget::UpdateButton::paintEvent(QPaintEvent *e) {
DialogsWidget::DialogsWidget(QWidget *parent, gsl::not_null<Window::Controller*> controller) : Window::AbstractSectionWidget(parent, controller)
, _mainMenuToggle(this, st::dialogsMenuToggle)
, _filter(this, st::dialogsFilter, langFactory(lng_dlg_filter))
, _searchFromUser(this, object_ptr<Ui::IconButton>(this, st::dialogsSearchFrom))
, _jumpToDate(this, object_ptr<Ui::IconButton>(this, st::dialogsCalendar))
, _cancelSearch(this, st::dialogsCancelSearch)
, _lockUnlock(this, st::dialogsLock)
@ -2358,7 +2359,8 @@ DialogsWidget::DialogsWidget(QWidget *parent, gsl::not_null<Window::Controller*>
subscribe(Adaptive::Changed(), [this] { updateForwardBar(); });
_cancelSearch->setClickedCallback([this] { onCancelSearch(); });
_jumpToDate->entity()->setClickedCallback([this] { if (_searchInPeer) App::main()->showJumpToDate(_searchInPeer, QDate()); });
_jumpToDate->entity()->setClickedCallback([this] { if (_searchInPeer) this->controller()->showJumpToDate(_searchInPeer, QDate()); });
_searchFromUser->entity()->setClickedCallback([this] { if (_searchInPeer->isChat() || _searchInPeer->isMegagroup()) showSearchFrom(); });
_lockUnlock->setVisible(Global::LocalPasscode());
subscribe(Global::RefLocalPasscodeChanged(), [this] { updateLockUnlockVisibility(); });
_lockUnlock->setClickedCallback([this] {
@ -2485,6 +2487,7 @@ void DialogsWidget::showAnimated(Window::SlideDirection direction, const Window:
_filter->hide();
_cancelSearch->hideFast();
_jumpToDate->hideFast();
_searchFromUser->hideFast();
_lockUnlock->hide();
int delta = st::slideShift;
@ -3059,6 +3062,10 @@ void DialogsWidget::setSearchInPeer(PeerData *peer) {
_inner->searchInPeer(_searchInPeer);
}
void DialogsWidget::showSearchFrom() {
}
void DialogsWidget::onFilterCursorMoved(int from, int to) {
if (to < 0) to = _filter->cursorPosition();
QString t = _filter->getLastText();
@ -3122,6 +3129,13 @@ void DialogsWidget::updateJumpToDateVisibility(bool fast) {
} else {
_jumpToDate->toggleAnimated(jumpToDateVisible);
}
auto searchFromUserVisible = _searchInPeer && (_searchInPeer->isChat() || _searchInPeer->isMegagroup());
if (fast) {
_searchFromUser->toggleFast(searchFromUserVisible);
} else {
_searchFromUser->toggleAnimated(searchFromUserVisible);
}
}
void DialogsWidget::updateControlsGeometry() {
@ -3144,6 +3158,7 @@ void DialogsWidget::updateControlsGeometry() {
_lockUnlock->moveToLeft(filterLeft + filterWidth + st::dialogsFilterPadding.x(), filterAreaTop + st::dialogsFilterPadding.y());
_cancelSearch->moveToLeft(filterLeft + filterWidth - _cancelSearch->width(), _filter->y());
_jumpToDate->moveToLeft(filterLeft + filterWidth - _jumpToDate->width(), _filter->y());
_searchFromUser->moveToLeft(filterLeft + filterWidth - _jumpToDate->width() - _searchFromUser->width(), _filter->y());
auto scrollTop = filterAreaTop + filterAreaHeight;
auto addToScroll = App::main() ? App::main()->contentScrollAddToY() : 0;

View File

@ -401,6 +401,7 @@ private:
void peerSearchReceived(const MTPcontacts_Found &result, mtpRequestId requestId);
void setSearchInPeer(PeerData *peer);
void showSearchFrom();
void showMainMenu();
void updateLockUnlockVisibility();
void updateJumpToDateVisibility(bool fast = false);
@ -429,6 +430,7 @@ private:
object_ptr<Ui::IconButton> _forwardCancel = { nullptr };
object_ptr<Ui::IconButton> _mainMenuToggle;
object_ptr<Ui::FlatInput> _filter;
object_ptr<Ui::WidgetScaledFadeWrap<Ui::IconButton>> _searchFromUser;
object_ptr<Ui::WidgetScaledFadeWrap<Ui::IconButton>> _jumpToDate;
object_ptr<Ui::CrossButton> _cancelSearch;
object_ptr<Ui::IconButton> _lockUnlock;

View File

@ -49,7 +49,7 @@ public:
}
void onClick(Qt::MouseButton) const override {
App::main()->showJumpToDate(_peer, _date);
App::wnd()->controller()->showJumpToDate(_peer, _date);
}
private:

View File

@ -66,7 +66,6 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "styles/style_boxes.h"
#include "mtproto/dc_options.h"
#include "core/file_utilities.h"
#include "boxes/calendar_box.h"
#include "auth_session.h"
#include "window/notifications_manager.h"
#include "window/window_controller.h"
@ -2991,97 +2990,6 @@ void MainWidget::dlgUpdated(PeerData *peer, MsgId msgId) {
}
}
void MainWidget::showJumpToDate(PeerData *peer, QDate requestedDate) {
Expects(peer != nullptr);
auto currentPeerDate = [peer] {
if (auto history = App::historyLoaded(peer)) {
if (history->scrollTopItem) {
return history->scrollTopItem->date.date();
} else if (history->loadedAtTop() && !history->isEmpty() && history->peer->migrateFrom()) {
if (auto migrated = App::historyLoaded(history->peer->migrateFrom())) {
if (migrated->scrollTopItem) {
// We're up in the migrated history.
// So current date is the date of first message here.
return history->blocks.front()->items.front()->date.date();
}
}
} else if (!history->lastMsgDate.isNull()) {
return history->lastMsgDate.date();
}
}
return QDate::currentDate();
};
auto maxPeerDate = [peer] {
if (auto history = App::historyLoaded(peer)) {
if (!history->lastMsgDate.isNull()) {
return history->lastMsgDate.date();
}
}
return QDate::currentDate();
};
auto minPeerDate = [peer] {
if (auto history = App::historyLoaded(peer)) {
if (history->loadedAtTop()) {
if (history->isEmpty()) {
return QDate::currentDate();
}
return history->blocks.front()->items.front()->date.date();
}
}
return QDate(2013, 8, 1); // Telegram was launched in August 2013 :)
};
auto highlighted = requestedDate.isNull() ? currentPeerDate() : requestedDate;
auto month = highlighted;
auto box = Box<CalendarBox>(month, highlighted, [this, peer](const QDate &date) { jumpToDate(peer, date); });
box->setMinDate(minPeerDate());
box->setMaxDate(maxPeerDate());
Ui::show(std::move(box));
}
void MainWidget::jumpToDate(PeerData *peer, const QDate &date) {
// API returns a message with date <= offset_date.
// So we request a message with offset_date = desired_date - 1 and add_offset = -1.
// This should give us the first message with date >= desired_date.
auto offset_date = static_cast<int>(QDateTime(date).toTime_t()) - 1;
auto add_offset = -1;
auto limit = 1;
auto flags = MTPmessages_Search::Flags(0);
auto request = MTPmessages_GetHistory(peer->input, MTP_int(0), MTP_int(offset_date), MTP_int(add_offset), MTP_int(limit), MTP_int(0), MTP_int(0));
MTP::send(request, ::rpcDone([peer](const MTPmessages_Messages &result) {
auto getMessagesList = [&result, peer]() -> const QVector<MTPMessage>* {
auto handleMessages = [](auto &messages) {
App::feedUsers(messages.vusers);
App::feedChats(messages.vchats);
return &messages.vmessages.v;
};
switch (result.type()) {
case mtpc_messages_messages: return handleMessages(result.c_messages_messages());
case mtpc_messages_messagesSlice: return handleMessages(result.c_messages_messagesSlice());
case mtpc_messages_channelMessages: {
auto &messages = result.c_messages_channelMessages();
if (peer && peer->isChannel()) {
peer->asChannel()->ptsReceived(messages.vpts.v);
} else {
LOG(("API Error: received messages.channelMessages when no channel was passed! (MainWidget::showJumpToDate)"));
}
return handleMessages(messages);
} break;
}
return nullptr;
};
if (auto list = getMessagesList()) {
App::feedMsgs(*list, NewMessageExisting);
for (auto &message : *list) {
auto id = idFromMessage(message);
Ui::showPeerHistory(peer, id);
return;
}
}
Ui::showPeerHistory(peer, ShowAtUnreadMsgId);
}));
}
void MainWidget::windowShown() {
_history->windowShown();
}
@ -3102,7 +3010,7 @@ bool MainWidget::deleteChannelFailed(const RPCError &error) {
void MainWidget::inviteToChannelDone(ChannelData *channel, const MTPUpdates &updates) {
sentUpdatesReceived(updates);
App::api()->requestParticipantsCountDelayed(channel);
AuthSession::Current().api().requestParticipantsCountDelayed(channel);
}
void MainWidget::historyToDown(History *history) {

View File

@ -187,8 +187,6 @@ public:
void dlgUpdated(Dialogs::Mode list, Dialogs::Row *row);
void dlgUpdated(PeerData *peer, MsgId msgId);
void showJumpToDate(PeerData *peer, QDate requestedDate);
void windowShown();
void sentUpdatesReceived(uint64 randomId, const MTPUpdates &updates);
@ -317,7 +315,7 @@ public:
void hideSingleUseKeyboard(PeerData *peer, MsgId replyTo);
bool insertBotCommand(const QString &cmd);
void jumpToDate(PeerData *peer, const QDate &date);
void jumpToDate(gsl::not_null<PeerData*> peer, const QDate &date);
void searchMessages(const QString &query, PeerData *inPeer);
bool preloadOverview(PeerData *peer, MediaOverviewType type);
void changingMsgId(HistoryItem *row, MsgId newId);

View File

@ -24,6 +24,9 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "mainwidget.h"
#include "styles/style_window.h"
#include "styles/style_dialogs.h"
#include "boxes/calendar_box.h"
#include "auth_session.h"
#include "apiwrap.h"
namespace Window {
@ -133,4 +136,51 @@ void Controller::provideChatWidth(int requestedWidth) {
}
}
void Controller::showJumpToDate(gsl::not_null<PeerData*> peer, QDate requestedDate) {
Expects(peer != nullptr);
auto currentPeerDate = [peer] {
if (auto history = App::historyLoaded(peer)) {
if (history->scrollTopItem) {
return history->scrollTopItem->date.date();
} else if (history->loadedAtTop() && !history->isEmpty() && history->peer->migrateFrom()) {
if (auto migrated = App::historyLoaded(history->peer->migrateFrom())) {
if (migrated->scrollTopItem) {
// We're up in the migrated history.
// So current date is the date of first message here.
return history->blocks.front()->items.front()->date.date();
}
}
} else if (!history->lastMsgDate.isNull()) {
return history->lastMsgDate.date();
}
}
return QDate::currentDate();
};
auto maxPeerDate = [peer] {
if (auto history = App::historyLoaded(peer)) {
if (!history->lastMsgDate.isNull()) {
return history->lastMsgDate.date();
}
}
return QDate::currentDate();
};
auto minPeerDate = [peer] {
if (auto history = App::historyLoaded(peer)) {
if (history->loadedAtTop()) {
if (history->isEmpty()) {
return QDate::currentDate();
}
return history->blocks.front()->items.front()->date.date();
}
}
return QDate(2013, 8, 1); // Telegram was launched in August 2013 :)
};
auto highlighted = requestedDate.isNull() ? currentPeerDate() : requestedDate;
auto month = highlighted;
auto box = Box<CalendarBox>(month, highlighted, [this, peer](const QDate &date) { AuthSession::Current().api().jumpToDate(peer, date); });
box->setMinDate(minPeerDate());
box->setMaxDate(maxPeerDate());
Ui::show(std::move(box));
}
} // namespace Window

View File

@ -80,6 +80,8 @@ public:
bool canProvideChatWidth(int requestedWidth) const;
void provideChatWidth(int requestedWidth);
void showJumpToDate(gsl::not_null<PeerData*> peer, QDate requestedDate);
base::Variable<float64> &dialogsWidthRatio() {
return _dialogsWidthRatio;
}