mirror of https://github.com/procxx/kepka.git
Improve support shortcuts handling.
This commit is contained in:
parent
219b824338
commit
496d711684
|
@ -26,6 +26,8 @@ const auto AutoRepeatCommands = base::flat_set<Command>{
|
||||||
Command::MediaNext,
|
Command::MediaNext,
|
||||||
Command::ChatPrevious,
|
Command::ChatPrevious,
|
||||||
Command::ChatNext,
|
Command::ChatNext,
|
||||||
|
Command::ChatFirst,
|
||||||
|
Command::ChatLast,
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto MediaCommands = base::flat_set<Command>{
|
const auto MediaCommands = base::flat_set<Command>{
|
||||||
|
@ -363,7 +365,7 @@ void Manager::set(const QString &keys, Command command) {
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
Qt::ApplicationShortcut);
|
Qt::ApplicationShortcut);
|
||||||
if (AutoRepeatCommands.contains(command)) {
|
if (!AutoRepeatCommands.contains(command)) {
|
||||||
shortcut->setAutoRepeat(false);
|
shortcut->setAutoRepeat(false);
|
||||||
}
|
}
|
||||||
const auto isMediaShortcut = MediaCommands.contains(command);
|
const auto isMediaShortcut = MediaCommands.contains(command);
|
||||||
|
|
|
@ -1758,6 +1758,14 @@ PeerData *DialogsInner::updateFromParentDrag(QPoint globalPosition) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DialogsInner::setLoadMoreCallback(Fn<void()> callback) {
|
||||||
|
_loadMoreCallback = std::move(callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
rpl::producer<> DialogsInner::listBottomReached() const {
|
||||||
|
return _listBottomReached.events();
|
||||||
|
}
|
||||||
|
|
||||||
void DialogsInner::visibleTopBottomUpdated(
|
void DialogsInner::visibleTopBottomUpdated(
|
||||||
int visibleTop,
|
int visibleTop,
|
||||||
int visibleBottom) {
|
int visibleBottom) {
|
||||||
|
@ -2803,21 +2811,40 @@ void DialogsInner::setupShortcuts() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto row = _controller->activeChatEntryCurrent();
|
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) {
|
if (row.key) {
|
||||||
const auto prev = computeJump(chatListEntryBefore(row), -1);
|
|
||||||
const auto next = computeJump(chatListEntryAfter(row), 1);
|
|
||||||
request->check(Command::ChatPrevious) && request->handle([=] {
|
request->check(Command::ChatPrevious) && request->handle([=] {
|
||||||
return jumpToDialogRow(prev);
|
return jumpToDialogRow(previous);
|
||||||
});
|
});
|
||||||
request->check(Command::ChatNext) && request->handle([=] {
|
request->check(Command::ChatNext) && request->handle([=] {
|
||||||
return jumpToDialogRow(next);
|
return jumpToDialogRow(next);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
request->check(Command::ChatFirst) && request->handle([=] {
|
request->check(Command::ChatFirst) && request->handle([=] {
|
||||||
return jumpToDialogRow(computeJump(chatListEntryFirst(), 1));
|
return jumpToDialogRow(first);
|
||||||
});
|
});
|
||||||
request->check(Command::ChatLast) && request->handle([=] {
|
request->check(Command::ChatLast) && request->handle([=] {
|
||||||
return jumpToDialogRow(computeJump(chatListEntryLast(), -1));
|
return jumpToDialogRow(last);
|
||||||
});
|
});
|
||||||
if (Auth().supportMode() && row.key.history()) {
|
if (Auth().supportMode() && row.key.history()) {
|
||||||
request->check(
|
request->check(
|
||||||
|
@ -2832,21 +2859,35 @@ void DialogsInner::setupShortcuts() {
|
||||||
|
|
||||||
Dialogs::RowDescriptor DialogsInner::computeJump(
|
Dialogs::RowDescriptor DialogsInner::computeJump(
|
||||||
const Dialogs::RowDescriptor &to,
|
const Dialogs::RowDescriptor &to,
|
||||||
int skipDirection) {
|
JumpSkip skip) {
|
||||||
auto result = to;
|
auto result = to;
|
||||||
if (Auth().supportMode()) {
|
if (Auth().supportMode() && result.key) {
|
||||||
while (result.key
|
const auto down = (skip == JumpSkip::NextOrEnd)
|
||||||
&& !result.key.entry()->chatListUnreadCount()
|
|| (skip == JumpSkip::NextOrOriginal);
|
||||||
|
while (!result.key.entry()->chatListUnreadCount()
|
||||||
&& !result.key.entry()->chatListUnreadMark()) {
|
&& !result.key.entry()->chatListUnreadMark()) {
|
||||||
result = (skipDirection > 0)
|
const auto next = down
|
||||||
? chatListEntryAfter(result)
|
? chatListEntryAfter(result)
|
||||||
: chatListEntryBefore(result);
|
: chatListEntryBefore(result);
|
||||||
|
if (next.key) {
|
||||||
|
result = next;
|
||||||
|
} else {
|
||||||
|
if (skip == JumpSkip::PreviousOrOriginal
|
||||||
|
|| skip == JumpSkip::NextOrOriginal) {
|
||||||
|
result = to;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DialogsInner::jumpToDialogRow(const Dialogs::RowDescriptor &to) {
|
bool DialogsInner::jumpToDialogRow(const Dialogs::RowDescriptor &to) {
|
||||||
|
if (to == chatListEntryLast()) {
|
||||||
|
_listBottomReached.fire({});
|
||||||
|
}
|
||||||
|
|
||||||
if (const auto history = to.key.history()) {
|
if (const auto history = to.key.history()) {
|
||||||
Ui::showPeerHistory(
|
Ui::showPeerHistory(
|
||||||
history,
|
history,
|
||||||
|
|
|
@ -93,9 +93,8 @@ public:
|
||||||
|
|
||||||
PeerData *updateFromParentDrag(QPoint globalPosition);
|
PeerData *updateFromParentDrag(QPoint globalPosition);
|
||||||
|
|
||||||
void setLoadMoreCallback(Fn<void()> callback) {
|
void setLoadMoreCallback(Fn<void()> callback);
|
||||||
_loadMoreCallback = std::move(callback);
|
[[nodiscard]] rpl::producer<> listBottomReached() const;
|
||||||
}
|
|
||||||
|
|
||||||
base::Observable<UserData*> searchFromUserChanged;
|
base::Observable<UserData*> searchFromUserChanged;
|
||||||
|
|
||||||
|
@ -141,6 +140,13 @@ private:
|
||||||
struct PeerSearchResult;
|
struct PeerSearchResult;
|
||||||
using PeerSearchResults = std::vector<std::unique_ptr<PeerSearchResult>>;
|
using PeerSearchResults = std::vector<std::unique_ptr<PeerSearchResult>>;
|
||||||
|
|
||||||
|
enum class JumpSkip {
|
||||||
|
PreviousOrBegin,
|
||||||
|
NextOrEnd,
|
||||||
|
PreviousOrOriginal,
|
||||||
|
NextOrOriginal,
|
||||||
|
};
|
||||||
|
|
||||||
struct ChosenRow {
|
struct ChosenRow {
|
||||||
Dialogs::Key key;
|
Dialogs::Key key;
|
||||||
Data::MessagePosition message;
|
Data::MessagePosition message;
|
||||||
|
@ -189,7 +195,7 @@ private:
|
||||||
void setupShortcuts();
|
void setupShortcuts();
|
||||||
Dialogs::RowDescriptor computeJump(
|
Dialogs::RowDescriptor computeJump(
|
||||||
const Dialogs::RowDescriptor &to,
|
const Dialogs::RowDescriptor &to,
|
||||||
int skipDirection);
|
JumpSkip skip);
|
||||||
bool jumpToDialogRow(const Dialogs::RowDescriptor &to);
|
bool jumpToDialogRow(const Dialogs::RowDescriptor &to);
|
||||||
|
|
||||||
Dialogs::RowDescriptor chatListEntryBefore(
|
Dialogs::RowDescriptor chatListEntryBefore(
|
||||||
|
@ -365,6 +371,7 @@ private:
|
||||||
Dialogs::Key _menuKey;
|
Dialogs::Key _menuKey;
|
||||||
|
|
||||||
Fn<void()> _loadMoreCallback;
|
Fn<void()> _loadMoreCallback;
|
||||||
|
rpl::event_stream<> _listBottomReached;
|
||||||
|
|
||||||
base::unique_qptr<Ui::PopupMenu> _menu;
|
base::unique_qptr<Ui::PopupMenu> _menu;
|
||||||
|
|
||||||
|
|
|
@ -85,7 +85,8 @@ struct RowDescriptor {
|
||||||
};
|
};
|
||||||
|
|
||||||
inline bool operator==(const RowDescriptor &a, const RowDescriptor &b) {
|
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) {
|
inline bool operator!=(const RowDescriptor &a, const RowDescriptor &b) {
|
||||||
|
|
|
@ -226,6 +226,10 @@ DialogsWidget::DialogsWidget(QWidget *parent, not_null<Window::Controller*> cont
|
||||||
loadDialogs();
|
loadDialogs();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
_inner->listBottomReached(
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
loadMoreBlockedByDateChats();
|
||||||
|
}, lifetime());
|
||||||
|
|
||||||
_filter->setFocusPolicy(Qt::StrongFocus);
|
_filter->setFocusPolicy(Qt::StrongFocus);
|
||||||
_filter->customUpDown(true);
|
_filter->customUpDown(true);
|
||||||
|
@ -530,14 +534,7 @@ void DialogsWidget::refreshLoadMoreButton() {
|
||||||
st::dialogsLoadMore,
|
st::dialogsLoadMore,
|
||||||
st::dialogsLoadMore);
|
st::dialogsLoadMore);
|
||||||
_loadMoreChats->addClickHandler([=] {
|
_loadMoreChats->addClickHandler([=] {
|
||||||
if (_loadMoreChats->isDisabled()) {
|
loadMoreBlockedByDateChats();
|
||||||
return;
|
|
||||||
}
|
|
||||||
const auto max = Auth().settings().supportChatsTimeSlice();
|
|
||||||
_dialogsLoadTill = _dialogsOffsetDate
|
|
||||||
? (_dialogsOffsetDate - max)
|
|
||||||
: (unixtime() - max);
|
|
||||||
loadDialogs();
|
|
||||||
});
|
});
|
||||||
updateControlsGeometry();
|
updateControlsGeometry();
|
||||||
}
|
}
|
||||||
|
@ -546,6 +543,17 @@ void DialogsWidget::refreshLoadMoreButton() {
|
||||||
_loadMoreChats->setText(loading ? "Loading..." : "Load more");
|
_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(
|
void DialogsWidget::pinnedDialogsReceived(
|
||||||
const MTPmessages_PeerDialogs &result,
|
const MTPmessages_PeerDialogs &result,
|
||||||
mtpRequestId requestId) {
|
mtpRequestId requestId) {
|
||||||
|
|
|
@ -165,6 +165,7 @@ private:
|
||||||
void refreshSupportFilteredResults();
|
void refreshSupportFilteredResults();
|
||||||
bool loadingBlockedByDate() const;
|
bool loadingBlockedByDate() const;
|
||||||
void refreshLoadMoreButton();
|
void refreshLoadMoreButton();
|
||||||
|
void loadMoreBlockedByDateChats();
|
||||||
|
|
||||||
bool dialogsFailed(const RPCError &error, mtpRequestId req);
|
bool dialogsFailed(const RPCError &error, mtpRequestId req);
|
||||||
bool searchFailed(DialogsSearchRequestType type, const RPCError &error, mtpRequestId req);
|
bool searchFailed(DialogsSearchRequestType type, const RPCError &error, mtpRequestId req);
|
||||||
|
|
Loading…
Reference in New Issue