Improve support shortcuts handling.

This commit is contained in:
John Preston 2018-12-29 17:09:45 +04:00
parent 219b824338
commit 496d711684
6 changed files with 84 additions and 24 deletions

View File

@ -26,6 +26,8 @@ const auto AutoRepeatCommands = base::flat_set<Command>{
Command::MediaNext,
Command::ChatPrevious,
Command::ChatNext,
Command::ChatFirst,
Command::ChatLast,
};
const auto MediaCommands = base::flat_set<Command>{
@ -363,7 +365,7 @@ void Manager::set(const QString &keys, Command command) {
nullptr,
nullptr,
Qt::ApplicationShortcut);
if (AutoRepeatCommands.contains(command)) {
if (!AutoRepeatCommands.contains(command)) {
shortcut->setAutoRepeat(false);
}
const auto isMediaShortcut = MediaCommands.contains(command);

View File

@ -1758,6 +1758,14 @@ PeerData *DialogsInner::updateFromParentDrag(QPoint globalPosition) {
return nullptr;
}
void DialogsInner::setLoadMoreCallback(Fn<void()> callback) {
_loadMoreCallback = std::move(callback);
}
rpl::producer<> DialogsInner::listBottomReached() const {
return _listBottomReached.events();
}
void DialogsInner::visibleTopBottomUpdated(
int visibleTop,
int visibleBottom) {
@ -2803,21 +2811,40 @@ void DialogsInner::setupShortcuts() {
return;
}
const auto row = _controller->activeChatEntryCurrent();
// Those should be computed before the call to request->handle.
const auto previous = row.key
? computeJump(
chatListEntryBefore(row),
JumpSkip::PreviousOrBegin)
: row;
const auto next = row.key
? computeJump(
chatListEntryAfter(row),
JumpSkip::NextOrEnd)
: row;
const auto first = [&] {
const auto to = chatListEntryFirst();
const auto jump = computeJump(to, JumpSkip::NextOrOriginal);
return (to == row || jump == row || to == previous) ? to : jump;
}();
const auto last = [&] {
const auto to = chatListEntryLast();
const auto jump = computeJump(to, JumpSkip::PreviousOrOriginal);
return (to == row || jump == row || to == next) ? to : jump;
}();
if (row.key) {
const auto prev = computeJump(chatListEntryBefore(row), -1);
const auto next = computeJump(chatListEntryAfter(row), 1);
request->check(Command::ChatPrevious) && request->handle([=] {
return jumpToDialogRow(prev);
return jumpToDialogRow(previous);
});
request->check(Command::ChatNext) && request->handle([=] {
return jumpToDialogRow(next);
});
}
request->check(Command::ChatFirst) && request->handle([=] {
return jumpToDialogRow(computeJump(chatListEntryFirst(), 1));
return jumpToDialogRow(first);
});
request->check(Command::ChatLast) && request->handle([=] {
return jumpToDialogRow(computeJump(chatListEntryLast(), -1));
return jumpToDialogRow(last);
});
if (Auth().supportMode() && row.key.history()) {
request->check(
@ -2832,21 +2859,35 @@ void DialogsInner::setupShortcuts() {
Dialogs::RowDescriptor DialogsInner::computeJump(
const Dialogs::RowDescriptor &to,
int skipDirection) {
JumpSkip skip) {
auto result = to;
if (Auth().supportMode()) {
while (result.key
&& !result.key.entry()->chatListUnreadCount()
if (Auth().supportMode() && result.key) {
const auto down = (skip == JumpSkip::NextOrEnd)
|| (skip == JumpSkip::NextOrOriginal);
while (!result.key.entry()->chatListUnreadCount()
&& !result.key.entry()->chatListUnreadMark()) {
result = (skipDirection > 0)
const auto next = down
? chatListEntryAfter(result)
: chatListEntryBefore(result);
if (next.key) {
result = next;
} else {
if (skip == JumpSkip::PreviousOrOriginal
|| skip == JumpSkip::NextOrOriginal) {
result = to;
}
break;
}
}
}
return result;
}
bool DialogsInner::jumpToDialogRow(const Dialogs::RowDescriptor &to) {
if (to == chatListEntryLast()) {
_listBottomReached.fire({});
}
if (const auto history = to.key.history()) {
Ui::showPeerHistory(
history,

View File

@ -93,9 +93,8 @@ public:
PeerData *updateFromParentDrag(QPoint globalPosition);
void setLoadMoreCallback(Fn<void()> callback) {
_loadMoreCallback = std::move(callback);
}
void setLoadMoreCallback(Fn<void()> callback);
[[nodiscard]] rpl::producer<> listBottomReached() const;
base::Observable<UserData*> searchFromUserChanged;
@ -141,6 +140,13 @@ private:
struct PeerSearchResult;
using PeerSearchResults = std::vector<std::unique_ptr<PeerSearchResult>>;
enum class JumpSkip {
PreviousOrBegin,
NextOrEnd,
PreviousOrOriginal,
NextOrOriginal,
};
struct ChosenRow {
Dialogs::Key key;
Data::MessagePosition message;
@ -189,7 +195,7 @@ private:
void setupShortcuts();
Dialogs::RowDescriptor computeJump(
const Dialogs::RowDescriptor &to,
int skipDirection);
JumpSkip skip);
bool jumpToDialogRow(const Dialogs::RowDescriptor &to);
Dialogs::RowDescriptor chatListEntryBefore(
@ -365,6 +371,7 @@ private:
Dialogs::Key _menuKey;
Fn<void()> _loadMoreCallback;
rpl::event_stream<> _listBottomReached;
base::unique_qptr<Ui::PopupMenu> _menu;

View File

@ -85,7 +85,8 @@ struct RowDescriptor {
};
inline bool operator==(const RowDescriptor &a, const RowDescriptor &b) {
return (a.key == b.key) && (a.fullId == b.fullId);
return (a.key == b.key)
&& ((a.fullId == b.fullId) || (!a.fullId.msg && !b.fullId.msg));
}
inline bool operator!=(const RowDescriptor &a, const RowDescriptor &b) {

View File

@ -226,6 +226,10 @@ DialogsWidget::DialogsWidget(QWidget *parent, not_null<Window::Controller*> cont
loadDialogs();
}
});
_inner->listBottomReached(
) | rpl::start_with_next([=] {
loadMoreBlockedByDateChats();
}, lifetime());
_filter->setFocusPolicy(Qt::StrongFocus);
_filter->customUpDown(true);
@ -530,14 +534,7 @@ void DialogsWidget::refreshLoadMoreButton() {
st::dialogsLoadMore,
st::dialogsLoadMore);
_loadMoreChats->addClickHandler([=] {
if (_loadMoreChats->isDisabled()) {
return;
}
const auto max = Auth().settings().supportChatsTimeSlice();
_dialogsLoadTill = _dialogsOffsetDate
? (_dialogsOffsetDate - max)
: (unixtime() - max);
loadDialogs();
loadMoreBlockedByDateChats();
});
updateControlsGeometry();
}
@ -546,6 +543,17 @@ void DialogsWidget::refreshLoadMoreButton() {
_loadMoreChats->setText(loading ? "Loading..." : "Load more");
}
void DialogsWidget::loadMoreBlockedByDateChats() {
if (!_loadMoreChats || _loadMoreChats->isDisabled()) {
return;
}
const auto max = Auth().settings().supportChatsTimeSlice();
_dialogsLoadTill = _dialogsOffsetDate
? (_dialogsOffsetDate - max)
: (unixtime() - max);
loadDialogs();
}
void DialogsWidget::pinnedDialogsReceived(
const MTPmessages_PeerDialogs &result,
mtpRequestId requestId) {

View File

@ -165,6 +165,7 @@ private:
void refreshSupportFilteredResults();
bool loadingBlockedByDate() const;
void refreshLoadMoreButton();
void loadMoreBlockedByDateChats();
bool dialogsFailed(const RPCError &error, mtpRequestId req);
bool searchFailed(DialogsSearchRequestType type, const RPCError &error, mtpRequestId req);