mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Fix finalizing media in non-active account.
This commit is contained in:
parent
000a7ae28b
commit
2f5cb33bf2
15 changed files with 396 additions and 304 deletions
|
@ -215,6 +215,8 @@ PRIVATE
|
||||||
api/api_hash.h
|
api/api_hash.h
|
||||||
api/api_self_destruct.cpp
|
api/api_self_destruct.cpp
|
||||||
api/api_self_destruct.h
|
api/api_self_destruct.h
|
||||||
|
api/api_send_progress.cpp
|
||||||
|
api/api_send_progress.h
|
||||||
api/api_sending.cpp
|
api/api_sending.cpp
|
||||||
api/api_sending.h
|
api/api_sending.h
|
||||||
api/api_sensitive_content.cpp
|
api/api_sensitive_content.cpp
|
||||||
|
|
105
Telegram/SourceFiles/api/api_send_progress.cpp
Normal file
105
Telegram/SourceFiles/api/api_send_progress.cpp
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop application for the Telegram messaging service.
|
||||||
|
|
||||||
|
For license and copyright information please follow this link:
|
||||||
|
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
*/
|
||||||
|
#include "api/api_send_progress.h"
|
||||||
|
|
||||||
|
#include "main/main_session.h"
|
||||||
|
#include "history/history.h"
|
||||||
|
#include "data/data_peer.h"
|
||||||
|
#include "apiwrap.h"
|
||||||
|
|
||||||
|
namespace Api {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
constexpr auto kCancelTypingActionTimeout = crl::time(5000);
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
SendProgressManager::SendProgressManager(not_null<Main::Session*> session)
|
||||||
|
: _session(session)
|
||||||
|
, _stopTypingTimer([=] { cancelTyping(base::take(_stopTypingHistory)); }) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void SendProgressManager::cancel(
|
||||||
|
not_null<History*> history,
|
||||||
|
SendProgressType type) {
|
||||||
|
const auto i = _requests.find({ history, type });
|
||||||
|
if (i != _requests.end()) {
|
||||||
|
_session->api().request(i->second).cancel();
|
||||||
|
_requests.erase(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SendProgressManager::cancelTyping(not_null<History*> history) {
|
||||||
|
_stopTypingTimer.cancel();
|
||||||
|
cancel(history, SendProgressType::Typing);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SendProgressManager::update(
|
||||||
|
not_null<History*> history,
|
||||||
|
SendProgressType type,
|
||||||
|
int32 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);
|
||||||
|
if (doing) {
|
||||||
|
send(history, type, progress);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SendProgressManager::send(
|
||||||
|
not_null<History*> history,
|
||||||
|
SendProgressType type,
|
||||||
|
int32 progress) {
|
||||||
|
using Type = SendProgressType;
|
||||||
|
MTPsendMessageAction action;
|
||||||
|
switch (type) {
|
||||||
|
case Type::Typing: action = MTP_sendMessageTypingAction(); break;
|
||||||
|
case Type::RecordVideo: action = MTP_sendMessageRecordVideoAction(); break;
|
||||||
|
case Type::UploadVideo: action = MTP_sendMessageUploadVideoAction(MTP_int(progress)); break;
|
||||||
|
case Type::RecordVoice: action = MTP_sendMessageRecordAudioAction(); break;
|
||||||
|
case Type::UploadVoice: action = MTP_sendMessageUploadAudioAction(MTP_int(progress)); break;
|
||||||
|
case Type::RecordRound: action = MTP_sendMessageRecordRoundAction(); break;
|
||||||
|
case Type::UploadRound: action = MTP_sendMessageUploadRoundAction(MTP_int(progress)); break;
|
||||||
|
case Type::UploadPhoto: action = MTP_sendMessageUploadPhotoAction(MTP_int(progress)); break;
|
||||||
|
case Type::UploadFile: action = MTP_sendMessageUploadDocumentAction(MTP_int(progress)); break;
|
||||||
|
case Type::ChooseLocation: action = MTP_sendMessageGeoLocationAction(); break;
|
||||||
|
case Type::ChooseContact: action = MTP_sendMessageChooseContactAction(); break;
|
||||||
|
case Type::PlayGame: action = MTP_sendMessageGamePlayAction(); break;
|
||||||
|
}
|
||||||
|
const auto requestId = _session->api().request(MTPmessages_SetTyping(
|
||||||
|
history->peer->input,
|
||||||
|
action
|
||||||
|
)).done([=](const MTPBool &result, mtpRequestId requestId) {
|
||||||
|
done(result, requestId);
|
||||||
|
}).send();
|
||||||
|
_requests.emplace(Key{ history, type }, requestId);
|
||||||
|
|
||||||
|
if (type == Type::Typing) {
|
||||||
|
_stopTypingHistory = history;
|
||||||
|
_stopTypingTimer.callOnce(kCancelTypingActionTimeout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SendProgressManager::done(
|
||||||
|
const MTPBool &result,
|
||||||
|
mtpRequestId requestId) {
|
||||||
|
for (auto i = _requests.begin(), e = _requests.end(); i != e; ++i) {
|
||||||
|
if (i->second == requestId) {
|
||||||
|
_requests.erase(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Api
|
88
Telegram/SourceFiles/api/api_send_progress.h
Normal file
88
Telegram/SourceFiles/api/api_send_progress.h
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop application for the Telegram messaging service.
|
||||||
|
|
||||||
|
For license and copyright information please follow this link:
|
||||||
|
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "api/api_common.h"
|
||||||
|
#include "base/timer.h"
|
||||||
|
|
||||||
|
class History;
|
||||||
|
|
||||||
|
namespace Main {
|
||||||
|
class Session;
|
||||||
|
} // namespace Main
|
||||||
|
|
||||||
|
namespace Api {
|
||||||
|
|
||||||
|
enum class SendProgressType {
|
||||||
|
Typing,
|
||||||
|
RecordVideo,
|
||||||
|
UploadVideo,
|
||||||
|
RecordVoice,
|
||||||
|
UploadVoice,
|
||||||
|
RecordRound,
|
||||||
|
UploadRound,
|
||||||
|
UploadPhoto,
|
||||||
|
UploadFile,
|
||||||
|
ChooseLocation,
|
||||||
|
ChooseContact,
|
||||||
|
PlayGame,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SendProgress {
|
||||||
|
SendProgress(
|
||||||
|
SendProgressType type,
|
||||||
|
crl::time until,
|
||||||
|
int progress = 0)
|
||||||
|
: type(type)
|
||||||
|
, until(until)
|
||||||
|
, progress(progress) {
|
||||||
|
}
|
||||||
|
SendProgressType type = SendProgressType::Typing;
|
||||||
|
crl::time until = 0;
|
||||||
|
int progress = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class SendProgressManager final {
|
||||||
|
public:
|
||||||
|
SendProgressManager(not_null<Main::Session*> session);
|
||||||
|
|
||||||
|
void update(
|
||||||
|
not_null<History*> history,
|
||||||
|
SendProgressType type,
|
||||||
|
int32 progress = 0);
|
||||||
|
void cancel(
|
||||||
|
not_null<History*> history,
|
||||||
|
SendProgressType type);
|
||||||
|
void cancelTyping(not_null<History*> history);
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct Key {
|
||||||
|
not_null<History*> history;
|
||||||
|
SendProgressType type = SendProgressType();
|
||||||
|
|
||||||
|
inline bool operator<(const Key &other) const {
|
||||||
|
return (history < other.history)
|
||||||
|
|| (history == other.history && type < other.type);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void send(
|
||||||
|
not_null<History*> history,
|
||||||
|
SendProgressType type,
|
||||||
|
int32 progress);
|
||||||
|
void done(const MTPBool &result, mtpRequestId requestId);
|
||||||
|
|
||||||
|
const not_null<Main::Session*> _session;
|
||||||
|
base::flat_map<Key, mtpRequestId> _requests;
|
||||||
|
base::Timer _stopTypingTimer;
|
||||||
|
History *_stopTypingHistory = nullptr;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Api
|
|
@ -15,6 +15,7 @@ struct FileLoadResult;
|
||||||
namespace Api {
|
namespace Api {
|
||||||
|
|
||||||
struct MessageToSend;
|
struct MessageToSend;
|
||||||
|
struct SendAction;
|
||||||
|
|
||||||
void SendExistingDocument(
|
void SendExistingDocument(
|
||||||
Api::MessageToSend &&message,
|
Api::MessageToSend &&message,
|
||||||
|
|
|
@ -422,35 +422,6 @@ inline bool operator==(
|
||||||
&& (a.scroll == b.scroll);
|
&& (a.scroll == b.scroll);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SendAction {
|
|
||||||
enum class Type {
|
|
||||||
Typing,
|
|
||||||
RecordVideo,
|
|
||||||
UploadVideo,
|
|
||||||
RecordVoice,
|
|
||||||
UploadVoice,
|
|
||||||
RecordRound,
|
|
||||||
UploadRound,
|
|
||||||
UploadPhoto,
|
|
||||||
UploadFile,
|
|
||||||
ChooseLocation,
|
|
||||||
ChooseContact,
|
|
||||||
PlayGame,
|
|
||||||
};
|
|
||||||
SendAction(
|
|
||||||
Type type,
|
|
||||||
crl::time until,
|
|
||||||
int progress = 0)
|
|
||||||
: type(type)
|
|
||||||
, until(until)
|
|
||||||
, progress(progress) {
|
|
||||||
}
|
|
||||||
Type type = Type::Typing;
|
|
||||||
crl::time until = 0;
|
|
||||||
int progress = 0;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
class FileClickHandler : public LeftButtonClickHandler {
|
class FileClickHandler : public LeftButtonClickHandler {
|
||||||
public:
|
public:
|
||||||
FileClickHandler(
|
FileClickHandler(
|
||||||
|
|
|
@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#include "history/history.h"
|
#include "history/history.h"
|
||||||
|
|
||||||
|
#include "api/api_send_progress.h"
|
||||||
#include "history/view/history_view_element.h"
|
#include "history/view/history_view_element.h"
|
||||||
#include "history/history_message.h"
|
#include "history/history_message.h"
|
||||||
#include "history/history_service.h"
|
#include "history/history_service.h"
|
||||||
|
@ -357,7 +358,7 @@ bool History::updateSendActionNeedsAnimating(
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
using Type = SendAction::Type;
|
using Type = Api::SendProgressType;
|
||||||
if (action.type() == mtpc_sendMessageCancelAction) {
|
if (action.type() == mtpc_sendMessageCancelAction) {
|
||||||
clearSendAction(user);
|
clearSendAction(user);
|
||||||
return false;
|
return false;
|
||||||
|
@ -420,7 +421,7 @@ bool History::updateSendActionNeedsAnimating(
|
||||||
return updateSendActionNeedsAnimating(now, true);
|
return updateSendActionNeedsAnimating(now, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool History::mySendActionUpdated(SendAction::Type type, bool doing) {
|
bool History::mySendActionUpdated(Api::SendProgressType type, bool doing) {
|
||||||
const auto now = crl::now();
|
const auto now = crl::now();
|
||||||
const auto i = _mySendActions.find(type);
|
const auto i = _mySendActions.find(type);
|
||||||
if (doing) {
|
if (doing) {
|
||||||
|
@ -508,7 +509,7 @@ bool History::updateSendActionNeedsAnimating(crl::time now, bool force) {
|
||||||
begin(_typing)->first->firstName);
|
begin(_typing)->first->firstName);
|
||||||
} else if (!_sendActions.empty()) {
|
} else if (!_sendActions.empty()) {
|
||||||
// Handles all actions except game playing.
|
// Handles all actions except game playing.
|
||||||
using Type = SendAction::Type;
|
using Type = Api::SendProgressType;
|
||||||
auto sendActionString = [](Type type, const QString &name) -> QString {
|
auto sendActionString = [](Type type, const QString &name) -> QString {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case Type::RecordVideo: return name.isEmpty() ? tr::lng_send_action_record_video(tr::now) : tr::lng_user_action_record_video(tr::now, lt_user, name);
|
case Type::RecordVideo: return name.isEmpty() ? tr::lng_send_action_record_video(tr::now) : tr::lng_user_action_record_video(tr::now, lt_user, name);
|
||||||
|
@ -562,7 +563,7 @@ bool History::updateSendActionNeedsAnimating(crl::time now, bool force) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (typingCount > 0) {
|
if (typingCount > 0) {
|
||||||
_sendActionAnimation.start(SendAction::Type::Typing);
|
_sendActionAnimation.start(Api::SendProgressType::Typing);
|
||||||
} else if (newTypingString.isEmpty()) {
|
} else if (newTypingString.isEmpty()) {
|
||||||
_sendActionAnimation.stop();
|
_sendActionAnimation.stop();
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,11 @@ class HistoryItem;
|
||||||
class HistoryMessage;
|
class HistoryMessage;
|
||||||
class HistoryService;
|
class HistoryService;
|
||||||
|
|
||||||
|
namespace Api {
|
||||||
|
enum class SendProgressType;
|
||||||
|
struct SendProgress;
|
||||||
|
} // namespace Api
|
||||||
|
|
||||||
namespace Main {
|
namespace Main {
|
||||||
class Session;
|
class Session;
|
||||||
} // namespace Main
|
} // namespace Main
|
||||||
|
@ -266,7 +271,7 @@ public:
|
||||||
bool hasPendingResizedItems() const;
|
bool hasPendingResizedItems() const;
|
||||||
void setHasPendingResizedItems();
|
void setHasPendingResizedItems();
|
||||||
|
|
||||||
bool mySendActionUpdated(SendAction::Type type, bool doing);
|
bool mySendActionUpdated(Api::SendProgressType type, bool doing);
|
||||||
bool paintSendAction(
|
bool paintSendAction(
|
||||||
Painter &p,
|
Painter &p,
|
||||||
int x,
|
int x,
|
||||||
|
@ -573,11 +578,11 @@ private:
|
||||||
QString _topPromotedType;
|
QString _topPromotedType;
|
||||||
|
|
||||||
base::flat_map<not_null<UserData*>, crl::time> _typing;
|
base::flat_map<not_null<UserData*>, crl::time> _typing;
|
||||||
base::flat_map<not_null<UserData*>, SendAction> _sendActions;
|
base::flat_map<not_null<UserData*>, Api::SendProgress> _sendActions;
|
||||||
QString _sendActionString;
|
QString _sendActionString;
|
||||||
Ui::Text::String _sendActionText;
|
Ui::Text::String _sendActionText;
|
||||||
Ui::SendActionAnimation _sendActionAnimation;
|
Ui::SendActionAnimation _sendActionAnimation;
|
||||||
base::flat_map<SendAction::Type, crl::time> _mySendActions;
|
base::flat_map<Api::SendProgressType, crl::time> _mySendActions;
|
||||||
|
|
||||||
std::deque<not_null<HistoryItem*>> _notifications;
|
std::deque<not_null<HistoryItem*>> _notifications;
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
#include "api/api_sending.h"
|
#include "api/api_sending.h"
|
||||||
#include "api/api_text_entities.h"
|
#include "api/api_text_entities.h"
|
||||||
|
#include "api/api_send_progress.h"
|
||||||
#include "boxes/confirm_box.h"
|
#include "boxes/confirm_box.h"
|
||||||
#include "boxes/send_files_box.h"
|
#include "boxes/send_files_box.h"
|
||||||
#include "boxes/share_box.h"
|
#include "boxes/share_box.h"
|
||||||
|
@ -123,7 +124,6 @@ constexpr auto kSkipRepaintWhileScrollMs = 100;
|
||||||
constexpr auto kShowMembersDropdownTimeoutMs = 300;
|
constexpr auto kShowMembersDropdownTimeoutMs = 300;
|
||||||
constexpr auto kDisplayEditTimeWarningMs = 300 * 1000;
|
constexpr auto kDisplayEditTimeWarningMs = 300 * 1000;
|
||||||
constexpr auto kFullDayInMs = 86400 * 1000;
|
constexpr auto kFullDayInMs = 86400 * 1000;
|
||||||
constexpr auto kCancelTypingActionTimeout = crl::time(5000);
|
|
||||||
constexpr auto kSaveDraftTimeout = 1000;
|
constexpr auto kSaveDraftTimeout = 1000;
|
||||||
constexpr auto kSaveDraftAnywayTimeout = 5000;
|
constexpr auto kSaveDraftAnywayTimeout = 5000;
|
||||||
constexpr auto kSaveCloudDraftIdleTimeout = 14000;
|
constexpr auto kSaveCloudDraftIdleTimeout = 14000;
|
||||||
|
@ -299,7 +299,6 @@ HistoryWidget::HistoryWidget(
|
||||||
, _attachDragState(DragState::None)
|
, _attachDragState(DragState::None)
|
||||||
, _attachDragDocument(this)
|
, _attachDragDocument(this)
|
||||||
, _attachDragPhoto(this)
|
, _attachDragPhoto(this)
|
||||||
, _sendActionStopTimer([this] { cancelTypingAction(); })
|
|
||||||
, _topShadow(this) {
|
, _topShadow(this) {
|
||||||
setAcceptDrops(true);
|
setAcceptDrops(true);
|
||||||
|
|
||||||
|
@ -737,7 +736,6 @@ HistoryWidget::HistoryWidget(
|
||||||
}
|
}
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
|
|
||||||
subscribeToUploader();
|
|
||||||
setupScheduledToggle();
|
setupScheduledToggle();
|
||||||
orderWidgets();
|
orderWidgets();
|
||||||
setupShortcuts();
|
setupShortcuts();
|
||||||
|
@ -1247,7 +1245,9 @@ void HistoryWidget::onTextChange() {
|
||||||
if (!_inlineBot
|
if (!_inlineBot
|
||||||
&& !_editMsgId
|
&& !_editMsgId
|
||||||
&& (_textUpdateEvents & TextUpdateEvent::SendTyping)) {
|
&& (_textUpdateEvents & TextUpdateEvent::SendTyping)) {
|
||||||
updateSendAction(_history, SendAction::Type::Typing);
|
session().sendProgressManager().update(
|
||||||
|
_history,
|
||||||
|
Api::SendProgressType::Typing);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1390,77 +1390,6 @@ void HistoryWidget::writeDrafts(Data::Draft **localDraft, Data::Draft **editDraf
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::cancelSendAction(
|
|
||||||
not_null<History*> history,
|
|
||||||
SendAction::Type type) {
|
|
||||||
const auto i = _sendActionRequests.find({ history, type });
|
|
||||||
if (i != _sendActionRequests.end()) {
|
|
||||||
_api.request(i->second).cancel();
|
|
||||||
_sendActionRequests.erase(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void HistoryWidget::cancelTypingAction() {
|
|
||||||
if (_history) {
|
|
||||||
cancelSendAction(_history, SendAction::Type::Typing);
|
|
||||||
}
|
|
||||||
_sendActionStopTimer.cancel();
|
|
||||||
}
|
|
||||||
|
|
||||||
void HistoryWidget::updateSendAction(
|
|
||||||
not_null<History*> history,
|
|
||||||
SendAction::Type type,
|
|
||||||
int32 progress) {
|
|
||||||
const auto peer = history->peer;
|
|
||||||
if (peer->isSelf() || (peer->isChannel() && !peer->isMegagroup())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto doing = (progress >= 0);
|
|
||||||
if (history->mySendActionUpdated(type, doing)) {
|
|
||||||
cancelSendAction(history, type);
|
|
||||||
if (doing) {
|
|
||||||
using Type = SendAction::Type;
|
|
||||||
MTPsendMessageAction action;
|
|
||||||
switch (type) {
|
|
||||||
case Type::Typing: action = MTP_sendMessageTypingAction(); break;
|
|
||||||
case Type::RecordVideo: action = MTP_sendMessageRecordVideoAction(); break;
|
|
||||||
case Type::UploadVideo: action = MTP_sendMessageUploadVideoAction(MTP_int(progress)); break;
|
|
||||||
case Type::RecordVoice: action = MTP_sendMessageRecordAudioAction(); break;
|
|
||||||
case Type::UploadVoice: action = MTP_sendMessageUploadAudioAction(MTP_int(progress)); break;
|
|
||||||
case Type::RecordRound: action = MTP_sendMessageRecordRoundAction(); break;
|
|
||||||
case Type::UploadRound: action = MTP_sendMessageUploadRoundAction(MTP_int(progress)); break;
|
|
||||||
case Type::UploadPhoto: action = MTP_sendMessageUploadPhotoAction(MTP_int(progress)); break;
|
|
||||||
case Type::UploadFile: action = MTP_sendMessageUploadDocumentAction(MTP_int(progress)); break;
|
|
||||||
case Type::ChooseLocation: action = MTP_sendMessageGeoLocationAction(); break;
|
|
||||||
case Type::ChooseContact: action = MTP_sendMessageChooseContactAction(); break;
|
|
||||||
case Type::PlayGame: action = MTP_sendMessageGamePlayAction(); break;
|
|
||||||
}
|
|
||||||
const auto requestId = _api.request(MTPmessages_SetTyping(
|
|
||||||
peer->input,
|
|
||||||
action
|
|
||||||
)).done([=](const MTPBool &result, mtpRequestId requestId) {
|
|
||||||
sendActionDone(result, requestId);
|
|
||||||
}).send();
|
|
||||||
_sendActionRequests.emplace(std::pair(history, type), requestId);
|
|
||||||
if (type == Type::Typing) {
|
|
||||||
_sendActionStopTimer.callOnce(kCancelTypingActionTimeout);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void HistoryWidget::sendActionDone(
|
|
||||||
const MTPBool &result,
|
|
||||||
mtpRequestId requestId) {
|
|
||||||
for (auto i = _sendActionRequests.begin(), e = _sendActionRequests.end(); i != e; ++i) {
|
|
||||||
if (i->second == requestId) {
|
|
||||||
_sendActionRequests.erase(i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void HistoryWidget::activate() {
|
void HistoryWidget::activate() {
|
||||||
if (_history) {
|
if (_history) {
|
||||||
if (!_historyInited) {
|
if (!_historyInited) {
|
||||||
|
@ -1515,7 +1444,9 @@ void HistoryWidget::onRecordUpdate(quint16 level, qint32 samples) {
|
||||||
Core::App().updateNonIdle();
|
Core::App().updateNonIdle();
|
||||||
updateField();
|
updateField();
|
||||||
if (_history) {
|
if (_history) {
|
||||||
updateSendAction(_history, SendAction::Type::RecordVoice);
|
session().sendProgressManager().update(
|
||||||
|
_history,
|
||||||
|
Api::SendProgressType::RecordVoice);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1795,9 +1726,12 @@ void HistoryWidget::showHistory(
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
updateSendAction(_history, SendAction::Type::Typing, -1);
|
session().sendProgressManager().update(
|
||||||
|
_history,
|
||||||
|
Api::SendProgressType::Typing,
|
||||||
|
-1);
|
||||||
session().data().histories().sendPendingReadInbox(_history);
|
session().data().histories().sendPendingReadInbox(_history);
|
||||||
cancelTypingAction();
|
session().sendProgressManager().cancelTyping(_history);
|
||||||
}
|
}
|
||||||
|
|
||||||
clearReplyReturns();
|
clearReplyReturns();
|
||||||
|
@ -3588,7 +3522,10 @@ void HistoryWidget::stopRecording(bool send) {
|
||||||
_recording = false;
|
_recording = false;
|
||||||
_recordingSamples = 0;
|
_recordingSamples = 0;
|
||||||
if (_history) {
|
if (_history) {
|
||||||
updateSendAction(_history, SendAction::Type::RecordVoice, -1);
|
session().sendProgressManager().update(
|
||||||
|
_history,
|
||||||
|
Api::SendProgressType::RecordVoice,
|
||||||
|
-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateControlsVisibility();
|
updateControlsVisibility();
|
||||||
|
@ -3689,22 +3626,13 @@ void HistoryWidget::app_sendBotCallback(
|
||||||
flags |= MTPmessages_GetBotCallbackAnswer::Flag::f_data;
|
flags |= MTPmessages_GetBotCallbackAnswer::Flag::f_data;
|
||||||
sendData = button->data;
|
sendData = button->data;
|
||||||
}
|
}
|
||||||
const auto weak = Ui::MakeWeak(this);
|
|
||||||
button->requestId = session().api().request(MTPmessages_GetBotCallbackAnswer(
|
button->requestId = session().api().request(MTPmessages_GetBotCallbackAnswer(
|
||||||
MTP_flags(flags),
|
MTP_flags(flags),
|
||||||
_peer->input,
|
_peer->input,
|
||||||
MTP_int(msg->id),
|
MTP_int(msg->id),
|
||||||
MTP_bytes(sendData)
|
MTP_bytes(sendData)
|
||||||
)).done([info, weak](const MTPmessages_BotCallbackAnswer &result, mtpRequestId requestId) {
|
)).done([info](const MTPmessages_BotCallbackAnswer &result, mtpRequestId requestId) {
|
||||||
BotCallbackDone(info, result, requestId);
|
BotCallbackDone(info, result, requestId);
|
||||||
result.match([&](const MTPDmessages_botCallbackAnswer &data) {
|
|
||||||
const auto item = info.session->data().message(info.msgId);
|
|
||||||
if (!data.vmessage() && data.vurl() && info.game && item) {
|
|
||||||
if (const auto strong = weak.data()) {
|
|
||||||
strong->updateSendAction(item->history(), SendAction::Type::PlayGame);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}).fail([info](const RPCError &error, mtpRequestId requestId) {
|
}).fail([info](const RPCError &error, mtpRequestId requestId) {
|
||||||
BotCallbackFail(info, error, requestId);
|
BotCallbackFail(info, error, requestId);
|
||||||
}).send();
|
}).send();
|
||||||
|
@ -3750,6 +3678,13 @@ void HistoryWidget::BotCallbackDone(
|
||||||
UrlClickHandler::Open(link);
|
UrlClickHandler::Open(link);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (const auto item = info.session->data().message(info.msgId)) {
|
||||||
|
if (!data.vmessage() && data.vurl() && info.game) {
|
||||||
|
info.session->sendProgressManager().update(
|
||||||
|
item->history(),
|
||||||
|
Api::SendProgressType::PlayGame);
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4654,144 +4589,6 @@ void HistoryWidget::uploadFile(
|
||||||
session().api().sendFile(fileContent, type, action);
|
session().api().sendFile(fileContent, type, action);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::subscribeToUploader() {
|
|
||||||
using namespace Storage;
|
|
||||||
|
|
||||||
session().uploader().photoReady(
|
|
||||||
) | rpl::start_with_next([=](const UploadedPhoto &data) {
|
|
||||||
if (data.edit) {
|
|
||||||
session().api().editUploadedFile(
|
|
||||||
data.fullId,
|
|
||||||
data.file,
|
|
||||||
std::nullopt,
|
|
||||||
data.options,
|
|
||||||
false);
|
|
||||||
} else {
|
|
||||||
session().api().sendUploadedPhoto(
|
|
||||||
data.fullId,
|
|
||||||
data.file,
|
|
||||||
data.options);
|
|
||||||
}
|
|
||||||
}, lifetime());
|
|
||||||
|
|
||||||
session().uploader().photoProgress(
|
|
||||||
) | rpl::start_with_next([=](const FullMsgId &fullId) {
|
|
||||||
photoProgress(fullId);
|
|
||||||
}, lifetime());
|
|
||||||
|
|
||||||
session().uploader().photoFailed(
|
|
||||||
) | rpl::start_with_next([=](const FullMsgId &fullId) {
|
|
||||||
photoFailed(fullId);
|
|
||||||
}, lifetime());
|
|
||||||
|
|
||||||
session().uploader().documentReady(
|
|
||||||
) | rpl::start_with_next([=](const UploadedDocument &data) {
|
|
||||||
if (data.edit) {
|
|
||||||
documentEdited(data.fullId, data.options, data.file);
|
|
||||||
} else {
|
|
||||||
documentUploaded(data.fullId, data.options, data.file);
|
|
||||||
}
|
|
||||||
}, lifetime());
|
|
||||||
|
|
||||||
session().uploader().thumbDocumentReady(
|
|
||||||
) | rpl::start_with_next([=](const UploadedThumbDocument &data) {
|
|
||||||
thumbDocumentUploaded(
|
|
||||||
data.fullId,
|
|
||||||
data.options,
|
|
||||||
data.file,
|
|
||||||
data.thumb,
|
|
||||||
data.edit);
|
|
||||||
}, lifetime());
|
|
||||||
|
|
||||||
session().uploader().documentProgress(
|
|
||||||
) | rpl::start_with_next([=](const FullMsgId &fullId) {
|
|
||||||
documentProgress(fullId);
|
|
||||||
}, lifetime());
|
|
||||||
|
|
||||||
session().uploader().documentFailed(
|
|
||||||
) | rpl::start_with_next([=](const FullMsgId &fullId) {
|
|
||||||
documentFailed(fullId);
|
|
||||||
}, lifetime());
|
|
||||||
}
|
|
||||||
|
|
||||||
void HistoryWidget::documentUploaded(
|
|
||||||
const FullMsgId &newId,
|
|
||||||
Api::SendOptions options,
|
|
||||||
const MTPInputFile &file) {
|
|
||||||
session().api().sendUploadedDocument(newId, file, std::nullopt, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
void HistoryWidget::documentEdited(
|
|
||||||
const FullMsgId &newId,
|
|
||||||
Api::SendOptions options,
|
|
||||||
const MTPInputFile &file) {
|
|
||||||
session().api().editUploadedFile(newId, file, std::nullopt, options, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void HistoryWidget::thumbDocumentUploaded(
|
|
||||||
const FullMsgId &newId,
|
|
||||||
Api::SendOptions options,
|
|
||||||
const MTPInputFile &file,
|
|
||||||
const MTPInputFile &thumb,
|
|
||||||
bool edit) {
|
|
||||||
if (edit) {
|
|
||||||
session().api().editUploadedFile(newId, file, thumb, options, true);
|
|
||||||
} else {
|
|
||||||
session().api().sendUploadedDocument(newId, file, thumb, options);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void HistoryWidget::photoProgress(const FullMsgId &newId) {
|
|
||||||
if (const auto item = session().data().message(newId)) {
|
|
||||||
const auto photo = item->media()
|
|
||||||
? item->media()->photo()
|
|
||||||
: nullptr;
|
|
||||||
updateSendAction(item->history(), SendAction::Type::UploadPhoto, 0);
|
|
||||||
session().data().requestItemRepaint(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void HistoryWidget::documentProgress(const FullMsgId &newId) {
|
|
||||||
if (const auto item = session().data().message(newId)) {
|
|
||||||
const auto media = item->media();
|
|
||||||
const auto document = media ? media->document() : nullptr;
|
|
||||||
const auto sendAction = (document && document->isVoiceMessage())
|
|
||||||
? SendAction::Type::UploadVoice
|
|
||||||
: SendAction::Type::UploadFile;
|
|
||||||
const auto progress = (document && document->uploading())
|
|
||||||
? document->uploadingData->offset
|
|
||||||
: 0;
|
|
||||||
|
|
||||||
updateSendAction(
|
|
||||||
item->history(),
|
|
||||||
sendAction,
|
|
||||||
progress);
|
|
||||||
session().data().requestItemRepaint(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void HistoryWidget::photoFailed(const FullMsgId &newId) {
|
|
||||||
if (const auto item = session().data().message(newId)) {
|
|
||||||
updateSendAction(
|
|
||||||
item->history(),
|
|
||||||
SendAction::Type::UploadPhoto,
|
|
||||||
-1);
|
|
||||||
session().data().requestItemRepaint(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void HistoryWidget::documentFailed(const FullMsgId &newId) {
|
|
||||||
if (const auto item = session().data().message(newId)) {
|
|
||||||
const auto media = item->media();
|
|
||||||
const auto document = media ? media->document() : nullptr;
|
|
||||||
const auto sendAction = (document && document->isVoiceMessage())
|
|
||||||
? SendAction::Type::UploadVoice
|
|
||||||
: SendAction::Type::UploadFile;
|
|
||||||
updateSendAction(item->history(), sendAction, -1);
|
|
||||||
session().data().requestItemRepaint(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void HistoryWidget::handleHistoryChange(not_null<const History*> history) {
|
void HistoryWidget::handleHistoryChange(not_null<const History*> history) {
|
||||||
if (_list && (_history == history || _migrated == history)) {
|
if (_list && (_history == history || _migrated == history)) {
|
||||||
handlePendingHistoryUpdate();
|
handlePendingHistoryUpdate();
|
||||||
|
|
|
@ -423,15 +423,6 @@ private:
|
||||||
void stopMessageHighlight();
|
void stopMessageHighlight();
|
||||||
|
|
||||||
auto computeSendButtonType() const;
|
auto computeSendButtonType() const;
|
||||||
void updateSendAction(
|
|
||||||
not_null<History*> history,
|
|
||||||
SendAction::Type type,
|
|
||||||
int32 progress = 0);
|
|
||||||
void cancelSendAction(
|
|
||||||
not_null<History*> history,
|
|
||||||
SendAction::Type type);
|
|
||||||
void cancelTypingAction();
|
|
||||||
void sendActionDone(const MTPBool &result, mtpRequestId requestId);
|
|
||||||
|
|
||||||
void animationCallback();
|
void animationCallback();
|
||||||
void updateOverStates(QPoint pos);
|
void updateOverStates(QPoint pos);
|
||||||
|
@ -474,28 +465,6 @@ private:
|
||||||
Api::SendOptions options,
|
Api::SendOptions options,
|
||||||
std::shared_ptr<SendingAlbum> album = nullptr);
|
std::shared_ptr<SendingAlbum> album = nullptr);
|
||||||
|
|
||||||
void subscribeToUploader();
|
|
||||||
|
|
||||||
void photoProgress(const FullMsgId &msgId);
|
|
||||||
void photoFailed(const FullMsgId &msgId);
|
|
||||||
void documentUploaded(
|
|
||||||
const FullMsgId &msgId,
|
|
||||||
Api::SendOptions options,
|
|
||||||
const MTPInputFile &file);
|
|
||||||
void thumbDocumentUploaded(
|
|
||||||
const FullMsgId &msgId,
|
|
||||||
Api::SendOptions options,
|
|
||||||
const MTPInputFile &file,
|
|
||||||
const MTPInputFile &thumb,
|
|
||||||
bool edit = false);
|
|
||||||
void documentProgress(const FullMsgId &msgId);
|
|
||||||
void documentFailed(const FullMsgId &msgId);
|
|
||||||
|
|
||||||
void documentEdited(
|
|
||||||
const FullMsgId &msgId,
|
|
||||||
Api::SendOptions options,
|
|
||||||
const MTPInputFile &file);
|
|
||||||
|
|
||||||
void itemRemoved(not_null<const HistoryItem*> item);
|
void itemRemoved(not_null<const HistoryItem*> item);
|
||||||
|
|
||||||
// Updates position of controls around the message field,
|
// Updates position of controls around the message field,
|
||||||
|
@ -800,11 +769,6 @@ private:
|
||||||
base::Timer _highlightTimer;
|
base::Timer _highlightTimer;
|
||||||
crl::time _highlightStart = 0;
|
crl::time _highlightStart = 0;
|
||||||
|
|
||||||
base::flat_map<
|
|
||||||
std::pair<not_null<History*>, SendAction::Type>,
|
|
||||||
mtpRequestId> _sendActionRequests;
|
|
||||||
base::Timer _sendActionStopTimer;
|
|
||||||
|
|
||||||
crl::time _saveDraftStart = 0;
|
crl::time _saveDraftStart = 0;
|
||||||
bool _saveDraftText = false;
|
bool _saveDraftText = false;
|
||||||
QTimer _saveDraftTimer, _saveCloudDraftTimer;
|
QTimer _saveDraftTimer, _saveCloudDraftTimer;
|
||||||
|
|
|
@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
#include "apiwrap.h"
|
#include "apiwrap.h"
|
||||||
#include "api/api_updates.h"
|
#include "api/api_updates.h"
|
||||||
|
#include "api/api_send_progress.h"
|
||||||
#include "core/application.h"
|
#include "core/application.h"
|
||||||
#include "main/main_account.h"
|
#include "main/main_account.h"
|
||||||
#include "main/main_domain.h"
|
#include "main/main_domain.h"
|
||||||
|
@ -72,6 +73,7 @@ Session::Session(
|
||||||
, _settings(std::move(settings))
|
, _settings(std::move(settings))
|
||||||
, _api(std::make_unique<ApiWrap>(this))
|
, _api(std::make_unique<ApiWrap>(this))
|
||||||
, _updates(std::make_unique<Api::Updates>(this))
|
, _updates(std::make_unique<Api::Updates>(this))
|
||||||
|
, _sendProgressManager(std::make_unique<Api::SendProgressManager>(this))
|
||||||
, _downloader(std::make_unique<Storage::DownloadManagerMtproto>(_api.get()))
|
, _downloader(std::make_unique<Storage::DownloadManagerMtproto>(_api.get()))
|
||||||
, _uploader(std::make_unique<Storage::Uploader>(_api.get()))
|
, _uploader(std::make_unique<Storage::Uploader>(_api.get()))
|
||||||
, _storage(std::make_unique<Storage::Facade>())
|
, _storage(std::make_unique<Storage::Facade>())
|
||||||
|
|
|
@ -16,6 +16,7 @@ class ApiWrap;
|
||||||
|
|
||||||
namespace Api {
|
namespace Api {
|
||||||
class Updates;
|
class Updates;
|
||||||
|
class SendProgressManager;
|
||||||
} // namespace Api
|
} // namespace Api
|
||||||
|
|
||||||
namespace MTP {
|
namespace MTP {
|
||||||
|
@ -87,6 +88,9 @@ public:
|
||||||
[[nodiscard]] Api::Updates &updates() const {
|
[[nodiscard]] Api::Updates &updates() const {
|
||||||
return *_updates;
|
return *_updates;
|
||||||
}
|
}
|
||||||
|
[[nodiscard]] Api::SendProgressManager &sendProgressManager() const {
|
||||||
|
return *_sendProgressManager;
|
||||||
|
}
|
||||||
[[nodiscard]] Storage::DownloadManagerMtproto &downloader() const {
|
[[nodiscard]] Storage::DownloadManagerMtproto &downloader() const {
|
||||||
return *_downloader;
|
return *_downloader;
|
||||||
}
|
}
|
||||||
|
@ -162,6 +166,7 @@ private:
|
||||||
const std::unique_ptr<SessionSettings> _settings;
|
const std::unique_ptr<SessionSettings> _settings;
|
||||||
const std::unique_ptr<ApiWrap> _api;
|
const std::unique_ptr<ApiWrap> _api;
|
||||||
const std::unique_ptr<Api::Updates> _updates;
|
const std::unique_ptr<Api::Updates> _updates;
|
||||||
|
const std::unique_ptr<Api::SendProgressManager> _sendProgressManager;
|
||||||
const std::unique_ptr<Storage::DownloadManagerMtproto> _downloader;
|
const std::unique_ptr<Storage::DownloadManagerMtproto> _downloader;
|
||||||
const std::unique_ptr<Storage::Uploader> _uploader;
|
const std::unique_ptr<Storage::Uploader> _uploader;
|
||||||
const std::unique_ptr<Storage::Facade> _storage;
|
const std::unique_ptr<Storage::Facade> _storage;
|
||||||
|
|
|
@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#include "storage/file_upload.h"
|
#include "storage/file_upload.h"
|
||||||
|
|
||||||
|
#include "api/api_send_progress.h"
|
||||||
#include "storage/localimageloader.h"
|
#include "storage/localimageloader.h"
|
||||||
#include "storage/file_download.h"
|
#include "storage/file_download.h"
|
||||||
#include "data/data_document.h"
|
#include "data/data_document.h"
|
||||||
|
@ -14,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "data/data_photo.h"
|
#include "data/data_photo.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "ui/image/image_location_factory.h"
|
#include "ui/image/image_location_factory.h"
|
||||||
|
#include "history/history_item.h"
|
||||||
#include "core/mime_type.h"
|
#include "core/mime_type.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
#include "apiwrap.h"
|
#include "apiwrap.h"
|
||||||
|
@ -153,6 +155,141 @@ Uploader::Uploader(not_null<ApiWrap*> api)
|
||||||
connect(&nextTimer, SIGNAL(timeout()), this, SLOT(sendNext()));
|
connect(&nextTimer, SIGNAL(timeout()), this, SLOT(sendNext()));
|
||||||
stopSessionsTimer.setSingleShot(true);
|
stopSessionsTimer.setSingleShot(true);
|
||||||
connect(&stopSessionsTimer, SIGNAL(timeout()), this, SLOT(stopSessions()));
|
connect(&stopSessionsTimer, SIGNAL(timeout()), this, SLOT(stopSessions()));
|
||||||
|
|
||||||
|
photoReady(
|
||||||
|
) | rpl::start_with_next([=](const UploadedPhoto &data) {
|
||||||
|
if (data.edit) {
|
||||||
|
_api->editUploadedFile(
|
||||||
|
data.fullId,
|
||||||
|
data.file,
|
||||||
|
std::nullopt,
|
||||||
|
data.options,
|
||||||
|
false);
|
||||||
|
} else {
|
||||||
|
_api->sendUploadedPhoto(
|
||||||
|
data.fullId,
|
||||||
|
data.file,
|
||||||
|
data.options);
|
||||||
|
}
|
||||||
|
}, _lifetime);
|
||||||
|
|
||||||
|
documentReady(
|
||||||
|
) | rpl::start_with_next([=](const UploadedDocument &data) {
|
||||||
|
if (data.edit) {
|
||||||
|
_api->editUploadedFile(
|
||||||
|
data.fullId,
|
||||||
|
data.file,
|
||||||
|
std::nullopt,
|
||||||
|
data.options,
|
||||||
|
true);
|
||||||
|
} else {
|
||||||
|
_api->sendUploadedDocument(
|
||||||
|
data.fullId,
|
||||||
|
data.file,
|
||||||
|
std::nullopt,
|
||||||
|
data.options);
|
||||||
|
}
|
||||||
|
}, _lifetime);
|
||||||
|
|
||||||
|
thumbDocumentReady(
|
||||||
|
) | rpl::start_with_next([=](const UploadedThumbDocument &data) {
|
||||||
|
if (data.edit) {
|
||||||
|
_api->editUploadedFile(
|
||||||
|
data.fullId,
|
||||||
|
data.file,
|
||||||
|
data.thumb,
|
||||||
|
data.options,
|
||||||
|
true);
|
||||||
|
} else {
|
||||||
|
_api->sendUploadedDocument(
|
||||||
|
data.fullId,
|
||||||
|
data.file,
|
||||||
|
data.thumb,
|
||||||
|
data.options);
|
||||||
|
}
|
||||||
|
}, _lifetime);
|
||||||
|
|
||||||
|
|
||||||
|
photoProgress(
|
||||||
|
) | rpl::start_with_next([=](const FullMsgId &fullId) {
|
||||||
|
processPhotoProgress(fullId);
|
||||||
|
}, _lifetime);
|
||||||
|
|
||||||
|
photoFailed(
|
||||||
|
) | rpl::start_with_next([=](const FullMsgId &fullId) {
|
||||||
|
processPhotoFailed(fullId);
|
||||||
|
}, _lifetime);
|
||||||
|
|
||||||
|
documentProgress(
|
||||||
|
) | rpl::start_with_next([=](const FullMsgId &fullId) {
|
||||||
|
processDocumentProgress(fullId);
|
||||||
|
}, _lifetime);
|
||||||
|
|
||||||
|
documentFailed(
|
||||||
|
) | rpl::start_with_next([=](const FullMsgId &fullId) {
|
||||||
|
processDocumentFailed(fullId);
|
||||||
|
}, _lifetime);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Uploader::processPhotoProgress(const FullMsgId &newId) {
|
||||||
|
const auto session = &_api->session();
|
||||||
|
if (const auto item = session->data().message(newId)) {
|
||||||
|
const auto photo = item->media()
|
||||||
|
? item->media()->photo()
|
||||||
|
: nullptr;
|
||||||
|
session->sendProgressManager().update(
|
||||||
|
item->history(),
|
||||||
|
Api::SendProgressType::UploadPhoto,
|
||||||
|
0);
|
||||||
|
session->data().requestItemRepaint(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Uploader::processDocumentProgress(const FullMsgId &newId) {
|
||||||
|
const auto session = &_api->session();
|
||||||
|
if (const auto item = session->data().message(newId)) {
|
||||||
|
const auto media = item->media();
|
||||||
|
const auto document = media ? media->document() : nullptr;
|
||||||
|
const auto sendAction = (document && document->isVoiceMessage())
|
||||||
|
? Api::SendProgressType::UploadVoice
|
||||||
|
: Api::SendProgressType::UploadFile;
|
||||||
|
const auto progress = (document && document->uploading())
|
||||||
|
? document->uploadingData->offset
|
||||||
|
: 0;
|
||||||
|
|
||||||
|
session->sendProgressManager().update(
|
||||||
|
item->history(),
|
||||||
|
sendAction,
|
||||||
|
progress);
|
||||||
|
session->data().requestItemRepaint(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Uploader::processPhotoFailed(const FullMsgId &newId) {
|
||||||
|
const auto session = &_api->session();
|
||||||
|
if (const auto item = session->data().message(newId)) {
|
||||||
|
session->sendProgressManager().update(
|
||||||
|
item->history(),
|
||||||
|
Api::SendProgressType::UploadPhoto,
|
||||||
|
-1);
|
||||||
|
session->data().requestItemRepaint(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Uploader::processDocumentFailed(const FullMsgId &newId) {
|
||||||
|
const auto session = &_api->session();
|
||||||
|
if (const auto item = session->data().message(newId)) {
|
||||||
|
const auto media = item->media();
|
||||||
|
const auto document = media ? media->document() : nullptr;
|
||||||
|
const auto sendAction = (document && document->isVoiceMessage())
|
||||||
|
? Api::SendProgressType::UploadVoice
|
||||||
|
: Api::SendProgressType::UploadFile;
|
||||||
|
session->sendProgressManager().update(
|
||||||
|
item->history(),
|
||||||
|
sendAction,
|
||||||
|
-1);
|
||||||
|
session->data().requestItemRepaint(item);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Uploader::~Uploader() {
|
Uploader::~Uploader() {
|
||||||
|
@ -282,7 +419,9 @@ void Uploader::stopSessions() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Uploader::sendNext() {
|
void Uploader::sendNext() {
|
||||||
if (sentSize >= kMaxUploadFileParallelSize || _pausedId.msg) return;
|
if (sentSize >= kMaxUploadFileParallelSize || _pausedId.msg) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
bool stopping = stopSessionsTimer.isActive();
|
bool stopping = stopSessionsTimer.isActive();
|
||||||
if (queue.empty()) {
|
if (queue.empty()) {
|
||||||
|
|
|
@ -121,6 +121,11 @@ private:
|
||||||
void partLoaded(const MTPBool &result, mtpRequestId requestId);
|
void partLoaded(const MTPBool &result, mtpRequestId requestId);
|
||||||
void partFailed(const RPCError &error, mtpRequestId requestId);
|
void partFailed(const RPCError &error, mtpRequestId requestId);
|
||||||
|
|
||||||
|
void processPhotoProgress(const FullMsgId &msgId);
|
||||||
|
void processPhotoFailed(const FullMsgId &msgId);
|
||||||
|
void processDocumentProgress(const FullMsgId &msgId);
|
||||||
|
void processDocumentFailed(const FullMsgId &msgId);
|
||||||
|
|
||||||
void currentFailed();
|
void currentFailed();
|
||||||
|
|
||||||
not_null<ApiWrap*> _api;
|
not_null<ApiWrap*> _api;
|
||||||
|
@ -147,6 +152,8 @@ private:
|
||||||
rpl::event_stream<FullMsgId> _documentFailed;
|
rpl::event_stream<FullMsgId> _documentFailed;
|
||||||
rpl::event_stream<FullMsgId> _secureFailed;
|
rpl::event_stream<FullMsgId> _secureFailed;
|
||||||
|
|
||||||
|
rpl::lifetime _lifetime;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Storage
|
} // namespace Storage
|
||||||
|
|
|
@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#include "ui/effects/send_action_animations.h"
|
#include "ui/effects/send_action_animations.h"
|
||||||
|
|
||||||
|
#include "api/api_send_progress.h"
|
||||||
#include "ui/effects/animation_value.h"
|
#include "ui/effects/animation_value.h"
|
||||||
#include "styles/style_widgets.h"
|
#include "styles/style_widgets.h"
|
||||||
|
|
||||||
|
@ -17,7 +18,7 @@ constexpr int kTypingDotsCount = 3;
|
||||||
constexpr int kRecordArcsCount = 4;
|
constexpr int kRecordArcsCount = 4;
|
||||||
constexpr int kUploadArrowsCount = 3;
|
constexpr int kUploadArrowsCount = 3;
|
||||||
|
|
||||||
using ImplementationsMap = QMap<SendAction::Type, const SendActionAnimation::Impl::MetaData*>;
|
using ImplementationsMap = QMap<Api::SendProgressType, const SendActionAnimation::Impl::MetaData*>;
|
||||||
NeverFreedPointer<ImplementationsMap> Implementations;
|
NeverFreedPointer<ImplementationsMap> Implementations;
|
||||||
|
|
||||||
class TypingAnimation : public SendActionAnimation::Impl {
|
class TypingAnimation : public SendActionAnimation::Impl {
|
||||||
|
@ -162,7 +163,7 @@ void CreateImplementationsMap() {
|
||||||
if (Implementations) {
|
if (Implementations) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
using Type = SendAction::Type;
|
using Type = Api::SendProgressType;
|
||||||
Implementations.createIfNull();
|
Implementations.createIfNull();
|
||||||
Type recordTypes[] = {
|
Type recordTypes[] = {
|
||||||
Type::RecordVideo,
|
Type::RecordVideo,
|
||||||
|
|
|
@ -7,11 +7,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
namespace Api {
|
||||||
|
enum class SendProgressType;
|
||||||
|
} // namespace Api
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
|
|
||||||
class SendActionAnimation {
|
class SendActionAnimation {
|
||||||
public:
|
public:
|
||||||
using Type = SendAction::Type;
|
using Type = Api::SendProgressType;
|
||||||
|
|
||||||
void start(Type type);
|
void start(Type type);
|
||||||
void stop();
|
void stop();
|
||||||
|
@ -31,7 +35,7 @@ public:
|
||||||
|
|
||||||
class Impl {
|
class Impl {
|
||||||
public:
|
public:
|
||||||
using Type = SendAction::Type;
|
using Type = Api::SendProgressType;
|
||||||
|
|
||||||
Impl(int period) : _period(period), _started(crl::now()) {
|
Impl(int period) : _period(period), _started(crl::now()) {
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue