mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-15 21:57:10 +02:00
Allow sending typing/send actions for Replies section.
This commit is contained in:
parent
f73b0f0b0d
commit
a287dec242
4 changed files with 74 additions and 48 deletions
|
@ -16,6 +16,7 @@ namespace Api {
|
|||
namespace {
|
||||
|
||||
constexpr auto kCancelTypingActionTimeout = crl::time(5000);
|
||||
constexpr auto kSetMyActionForMs = 10 * crl::time(1000);
|
||||
|
||||
} // namespace
|
||||
|
||||
|
@ -27,7 +28,14 @@ SendProgressManager::SendProgressManager(not_null<Main::Session*> session)
|
|||
void SendProgressManager::cancel(
|
||||
not_null<History*> history,
|
||||
SendProgressType type) {
|
||||
const auto i = _requests.find({ history, type });
|
||||
cancel(history, 0, type);
|
||||
}
|
||||
|
||||
void SendProgressManager::cancel(
|
||||
not_null<History*> history,
|
||||
MsgId topMsgId,
|
||||
SendProgressType type) {
|
||||
const auto i = _requests.find(Key{ history, topMsgId, type });
|
||||
if (i != _requests.end()) {
|
||||
_session->api().request(i->second).cancel();
|
||||
_requests.erase(i);
|
||||
|
@ -42,29 +50,58 @@ void SendProgressManager::cancelTyping(not_null<History*> history) {
|
|||
void SendProgressManager::update(
|
||||
not_null<History*> history,
|
||||
SendProgressType type,
|
||||
int32 progress) {
|
||||
int progress) {
|
||||
update(history, 0, type, progress);
|
||||
}
|
||||
|
||||
void SendProgressManager::update(
|
||||
not_null<History*> history,
|
||||
MsgId topMsgId,
|
||||
SendProgressType type,
|
||||
int progress) {
|
||||
const auto peer = history->peer;
|
||||
if (peer->isSelf() || (peer->isChannel() && !peer->isMegagroup())) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto doing = (progress >= 0);
|
||||
if (history->mySendActionUpdated(type, doing)) {
|
||||
cancel(history, type);
|
||||
const auto key = Key{ history, topMsgId, type };
|
||||
if (updated(key, doing)) {
|
||||
cancel(history, topMsgId, type);
|
||||
if (doing) {
|
||||
send(history, type, progress);
|
||||
send(key, progress);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SendProgressManager::send(
|
||||
not_null<History*> history,
|
||||
SendProgressType type,
|
||||
int32 progress) {
|
||||
bool SendProgressManager::updated(const Key &key, bool doing) {
|
||||
const auto now = crl::now();
|
||||
const auto i = _updated.find(key);
|
||||
if (doing) {
|
||||
if (i == end(_updated)) {
|
||||
_updated.emplace(key, now + kSetMyActionForMs);
|
||||
} else if (i->second > now + (kSetMyActionForMs / 2)) {
|
||||
return false;
|
||||
} else {
|
||||
i->second = now + kSetMyActionForMs;
|
||||
}
|
||||
} else {
|
||||
if (i == end(_updated)) {
|
||||
return false;
|
||||
} else if (i->second <= now) {
|
||||
return false;
|
||||
} else {
|
||||
_updated.erase(i);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void SendProgressManager::send(const Key &key, int progress) {
|
||||
using Type = SendProgressType;
|
||||
const auto action = [&]() -> MTPsendMessageAction {
|
||||
const auto p = MTP_int(progress);
|
||||
switch (type) {
|
||||
switch (key.type) {
|
||||
case Type::Typing: return MTP_sendMessageTypingAction();
|
||||
case Type::RecordVideo: return MTP_sendMessageRecordVideoAction();
|
||||
case Type::UploadVideo: return MTP_sendMessageUploadVideoAction(p);
|
||||
|
@ -81,17 +118,19 @@ void SendProgressManager::send(
|
|||
}
|
||||
}();
|
||||
const auto requestId = _session->api().request(MTPmessages_SetTyping(
|
||||
MTP_flags(0),
|
||||
history->peer->input,
|
||||
MTP_int(0), // top_msg_id
|
||||
MTP_flags(key.topMsgId
|
||||
? MTPmessages_SetTyping::Flag::f_top_msg_id
|
||||
: MTPmessages_SetTyping::Flag(0)),
|
||||
key.history->peer->input,
|
||||
MTP_int(key.topMsgId),
|
||||
action
|
||||
)).done([=](const MTPBool &result, mtpRequestId requestId) {
|
||||
done(result, requestId);
|
||||
}).send();
|
||||
_requests.emplace(Key{ history, type }, requestId);
|
||||
_requests.emplace(key, requestId);
|
||||
|
||||
if (type == Type::Typing) {
|
||||
_stopTypingHistory = history;
|
||||
if (key.type == Type::Typing) {
|
||||
_stopTypingHistory = key.history;
|
||||
_stopTypingTimer.callOnce(kCancelTypingActionTimeout);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,7 +55,16 @@ public:
|
|||
void update(
|
||||
not_null<History*> history,
|
||||
SendProgressType type,
|
||||
int32 progress = 0);
|
||||
int progress = 0);
|
||||
void update(
|
||||
not_null<History*> history,
|
||||
MsgId topMsgId,
|
||||
SendProgressType type,
|
||||
int progress = 0);
|
||||
void cancel(
|
||||
not_null<History*> history,
|
||||
MsgId topMsgId,
|
||||
SendProgressType type);
|
||||
void cancel(
|
||||
not_null<History*> history,
|
||||
SendProgressType type);
|
||||
|
@ -64,22 +73,26 @@ public:
|
|||
private:
|
||||
struct Key {
|
||||
not_null<History*> history;
|
||||
MsgId topMsgId = 0;
|
||||
SendProgressType type = SendProgressType();
|
||||
|
||||
inline bool operator<(const Key &other) const {
|
||||
return (history < other.history)
|
||||
|| (history == other.history && type < other.type);
|
||||
|| (history == other.history && topMsgId < other.topMsgId)
|
||||
|| (history == other.history
|
||||
&& topMsgId == other.topMsgId
|
||||
&& type < other.type);
|
||||
}
|
||||
};
|
||||
|
||||
void send(
|
||||
not_null<History*> history,
|
||||
SendProgressType type,
|
||||
int32 progress);
|
||||
bool updated(const Key &key, bool doing);
|
||||
|
||||
void send(const Key &key, int progress);
|
||||
void done(const MTPBool &result, mtpRequestId requestId);
|
||||
|
||||
const not_null<Main::Session*> _session;
|
||||
base::flat_map<Key, mtpRequestId> _requests;
|
||||
base::flat_map<Key, crl::time> _updated;
|
||||
base::Timer _stopTypingTimer;
|
||||
History *_stopTypingHistory = nullptr;
|
||||
|
||||
|
|
|
@ -62,7 +62,6 @@ constexpr auto kStatusShowClientsideUploadFile = 6000;
|
|||
constexpr auto kStatusShowClientsideChooseLocation = 6000;
|
||||
constexpr auto kStatusShowClientsideChooseContact = 6000;
|
||||
constexpr auto kStatusShowClientsidePlayGame = 10000;
|
||||
constexpr auto kSetMyActionForMs = 10000;
|
||||
constexpr auto kNewBlockEachMessage = 50;
|
||||
constexpr auto kSkipCloudDraftsFor = TimeId(3);
|
||||
|
||||
|
@ -421,29 +420,6 @@ bool History::updateSendActionNeedsAnimating(
|
|||
return updateSendActionNeedsAnimating(now, true);
|
||||
}
|
||||
|
||||
bool History::mySendActionUpdated(Api::SendProgressType type, bool doing) {
|
||||
const auto now = crl::now();
|
||||
const auto i = _mySendActions.find(type);
|
||||
if (doing) {
|
||||
if (i == end(_mySendActions)) {
|
||||
_mySendActions.emplace(type, now + kSetMyActionForMs);
|
||||
} else if (i->second > now + (kSetMyActionForMs / 2)) {
|
||||
return false;
|
||||
} else {
|
||||
i->second = now + kSetMyActionForMs;
|
||||
}
|
||||
} else {
|
||||
if (i == end(_mySendActions)) {
|
||||
return false;
|
||||
} else if (i->second <= now) {
|
||||
return false;
|
||||
} else {
|
||||
_mySendActions.erase(i);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool History::paintSendAction(
|
||||
Painter &p,
|
||||
int x,
|
||||
|
|
|
@ -276,7 +276,6 @@ public:
|
|||
bool hasPendingResizedItems() const;
|
||||
void setHasPendingResizedItems();
|
||||
|
||||
bool mySendActionUpdated(Api::SendProgressType type, bool doing);
|
||||
bool paintSendAction(
|
||||
Painter &p,
|
||||
int x,
|
||||
|
@ -587,7 +586,6 @@ private:
|
|||
QString _sendActionString;
|
||||
Ui::Text::String _sendActionText;
|
||||
Ui::SendActionAnimation _sendActionAnimation;
|
||||
base::flat_map<Api::SendProgressType, crl::time> _mySendActions;
|
||||
|
||||
std::deque<not_null<HistoryItem*>> _notifications;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue