diff --git a/Telegram/PrepareWin.bat b/Telegram/PrepareWin.bat index 04bd71215e..696e34b23c 100644 --- a/Telegram/PrepareWin.bat +++ b/Telegram/PrepareWin.bat @@ -1,11 +1,11 @@ @echo OFF set "AppVersionStrMajor=0.8" -set "AppVersion=8043" -set "AppVersionStrSmall=0.8.43" -set "AppVersionStr=0.8.43" -set "AppVersionStrFull=0.8.43.0" -set "DevChannel=0" +set "AppVersion=8044" +set "AppVersionStrSmall=0.8.44" +set "AppVersionStr=0.8.44" +set "AppVersionStrFull=0.8.44.0" +set "DevChannel=1" if %DevChannel% neq 0 goto preparedev diff --git a/Telegram/Resources/lang.strings b/Telegram/Resources/lang.strings index 2a1e9f8fcb..0d30dce6da 100644 --- a/Telegram/Resources/lang.strings +++ b/Telegram/Resources/lang.strings @@ -478,6 +478,22 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org "lng_user_typing" = "{user} is typing"; "lng_users_typing" = "{user} and {second_user} are typing"; "lng_many_typing" = "{count:_not_used_|# is|# are} typing"; +"lng_send_action_record_video" = "recording video"; +"lng_user_action_record_video" = "{user} is recording video"; +"lng_send_action_upload_video" = "sending video"; +"lng_user_action_upload_video" = "{user} is sending video"; +"lng_send_action_record_audio" = "recording audio"; +"lng_user_action_record_audio" = "{user} is recording audio"; +"lng_send_action_upload_audio" = "sending audio"; +"lng_user_action_upload_audio" = "{user} is sending audio"; +"lng_send_action_upload_photo" = "sending photo"; +"lng_user_action_upload_photo" = "{user} is sending photo"; +"lng_send_action_upload_file" = "sending file"; +"lng_user_action_upload_file" = "{user} is sending file"; +"lng_send_action_geo_location" = "choosing location"; +"lng_user_action_geo_location" = "{user} is choosing location"; +"lng_send_action_choose_contact" = "choosing contact"; +"lng_user_action_choose_contact" = "{user} is choosing contact"; "lng_unread_bar" = "{count:_not_used_|# unread message|# unread messages}"; "lng_maps_point" = "Location"; diff --git a/Telegram/SourceFiles/application.cpp b/Telegram/SourceFiles/application.cpp index 517b29afd9..8f14416b8f 100644 --- a/Telegram/SourceFiles/application.cpp +++ b/Telegram/SourceFiles/application.cpp @@ -658,8 +658,8 @@ void Application::checkMapVersion() { psRegisterCustomScheme(); if (Local::oldMapVersion()) { QString versionFeatures; - if (cDevVersion() && Local::oldMapVersion() < 8042) { - versionFeatures = QString::fromUtf8("\xe2\x80\x94 Dev version will now get updated to stable as well");// .replace('@', qsl("@") + QChar(0x200D)); + if (cDevVersion() && Local::oldMapVersion() < 8044) { + versionFeatures = QString::fromUtf8("\xe2\x80\x94 Sending media and recording audio status display");// .replace('@', qsl("@") + QChar(0x200D)); } else if (!cDevVersion() && Local::oldMapVersion() < 8043) { versionFeatures = lang(lng_new_version_minor).trimmed(); } diff --git a/Telegram/SourceFiles/config.h b/Telegram/SourceFiles/config.h index e4f6476b7a..740f3b96ef 100644 --- a/Telegram/SourceFiles/config.h +++ b/Telegram/SourceFiles/config.h @@ -17,9 +17,9 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org */ #pragma once -static const int32 AppVersion = 8043; -static const wchar_t *AppVersionStr = L"0.8.43"; -static const bool DevVersion = false; +static const int32 AppVersion = 8044; +static const wchar_t *AppVersionStr = L"0.8.44"; +static const bool DevVersion = true; static const wchar_t *AppNameOld = L"Telegram Win (Unofficial)"; static const wchar_t *AppName = L"Telegram Desktop"; diff --git a/Telegram/SourceFiles/fileuploader.cpp b/Telegram/SourceFiles/fileuploader.cpp index 82813f5ab6..45d1980853 100644 --- a/Telegram/SourceFiles/fileuploader.cpp +++ b/Telegram/SourceFiles/fileuploader.cpp @@ -273,6 +273,7 @@ void FileUploader::partLoaded(const MTPBool &result, mtpRequestId requestId) { audio->uploadOffset = audio->size; } } + emit audioProgress(k.key()); } } } diff --git a/Telegram/SourceFiles/history.cpp b/Telegram/SourceFiles/history.cpp index 2a7e70c4cd..1d9e7a74fa 100644 --- a/Telegram/SourceFiles/history.cpp +++ b/Telegram/SourceFiles/history.cpp @@ -167,7 +167,7 @@ void DialogRow::paint(QPainter &p, int32 w, bool act, bool sel) const { if (!last) { p.setFont(st::dlgHistFont->f); p.setPen((act ? st::dlgActiveColor : st::dlgSystemColor)->p); - if (history->typing.isEmpty()) { + if (history->typing.isEmpty() && history->sendActions.isEmpty()) { p.drawText(nameleft, st::dlgPaddingVer + st::dlgFont->height + st::dlgFont->ascent + st::dlgSep, lang(lng_empty_history)); } else { history->typingText.drawElided(p, nameleft, st::dlgPaddingVer + st::dlgFont->height + st::dlgSep, namewidth); @@ -223,7 +223,7 @@ void DialogRow::paint(QPainter &p, int32 w, bool act, bool sel) const { p.setPen((act ? st::dlgActiveUnreadColor : st::dlgUnreadColor)->p); p.drawText(unreadRectLeft + st::dlgUnreadPaddingHor, unreadRectTop + st::dlgUnreadPaddingVer + st::dlgUnreadFont->ascent, unreadStr); } - if (history->typing.isEmpty()) { + if (history->typing.isEmpty() && history->sendActions.isEmpty()) { last->drawInDialog(p, QRect(nameleft, st::dlgPaddingVer + st::dlgFont->height + st::dlgSep, lastWidth, st::dlgFont->height), act, history->textCachedFor, history->lastItemTextCache); } else { p.setPen((act ? st::dlgActiveColor : st::dlgSystemColor)->p); @@ -319,7 +319,6 @@ History::History(const PeerId &peerId) : width(0), height(0) , lastItemTextCache(st::dlgRichMinWidth) , posInDialogs(0) , typingText(st::dlgRichMinWidth) -, myTyping(0) { for (int32 i = 0; i < OverviewCount; ++i) { _overviewCount[i] = -1; // not loaded yet @@ -347,6 +346,14 @@ bool History::updateTyping(uint64 ms, uint32 dots, bool force) { ++i; } } + for (SendActionUsers::iterator i = sendActions.begin(), e = sendActions.end(); i != e;) { + if (ms >= i.value().until) { + i = sendActions.erase(i); + changed = true; + } else { + ++i; + } + } if (changed) { QString newTypingStr; int32 cnt = typing.size(); @@ -356,6 +363,17 @@ bool History::updateTyping(uint64 ms, uint32 dots, bool force) { newTypingStr = lng_users_typing(lt_user, typing.begin().key()->firstName, lt_second_user, (typing.end() - 1).key()->firstName); } else if (cnt) { newTypingStr = peer->chat ? lng_user_typing(lt_user, typing.begin().key()->firstName) : lang(lng_typing); + } else if (!sendActions.isEmpty()) { + switch (sendActions.begin().value().type) { + case SendActionRecordVideo: newTypingStr = peer->chat ? lng_user_action_record_video(lt_user, sendActions.begin().key()->firstName) : lang(lng_send_action_record_video); break; + case SendActionUploadVideo: newTypingStr = peer->chat ? lng_user_action_upload_video(lt_user, sendActions.begin().key()->firstName) : lang(lng_send_action_upload_video); break; + case SendActionRecordAudio: newTypingStr = peer->chat ? lng_user_action_record_audio(lt_user, sendActions.begin().key()->firstName) : lang(lng_send_action_record_audio); break; + case SendActionUploadAudio: newTypingStr = peer->chat ? lng_user_action_upload_audio(lt_user, sendActions.begin().key()->firstName) : lang(lng_send_action_upload_audio); break; + case SendActionUploadPhoto: newTypingStr = peer->chat ? lng_user_action_upload_photo(lt_user, sendActions.begin().key()->firstName) : lang(lng_send_action_upload_photo); break; + case SendActionUploadFile: newTypingStr = peer->chat ? lng_user_action_upload_file(lt_user, sendActions.begin().key()->firstName) : lang(lng_send_action_upload_file); break; + case SendActionChooseLocation: newTypingStr = peer->chat ? lng_user_action_geo_location(lt_user, sendActions.begin().key()->firstName) : lang(lng_send_action_geo_location); break; + case SendActionChooseContact: newTypingStr = peer->chat ? lng_user_action_choose_contact(lt_user, sendActions.begin().key()->firstName) : lang(lng_send_action_choose_contact); break; + } } if (!newTypingStr.isEmpty()) { newTypingStr += qsl("..."); @@ -506,9 +524,25 @@ void Histories::clear() { Parent::clear(); } -void Histories::regTyping(History *history, UserData *user) { +void Histories::regSendAction(History *history, UserData *user, const MTPSendMessageAction &action) { + if (action.type() == mtpc_sendMessageCancelAction) { + history->unregTyping(user); + return; + } + uint64 ms = getms(true); - history->typing[user] = ms + 6000; + switch (action.type()) { + case mtpc_sendMessageTypingAction: history->typing[user] = ms + 6000; break; + case mtpc_sendMessageRecordVideoAction: history->sendActions.insert(user, SendAction(SendActionRecordVideo, ms + 6000)); break; + case mtpc_sendMessageUploadVideoAction: history->sendActions.insert(user, SendAction(SendActionUploadVideo, ms + 6000, action.c_sendMessageUploadVideoAction().vprogress.v)); break; + case mtpc_sendMessageRecordAudioAction: history->sendActions.insert(user, SendAction(SendActionRecordAudio, ms + 6000)); break; + case mtpc_sendMessageUploadAudioAction: history->sendActions.insert(user, SendAction(SendActionUploadAudio, ms + 6000, action.c_sendMessageUploadAudioAction().vprogress.v)); break; + case mtpc_sendMessageUploadPhotoAction: history->sendActions.insert(user, SendAction(SendActionUploadPhoto, ms + 6000, action.c_sendMessageUploadPhotoAction().vprogress.v)); break; + case mtpc_sendMessageUploadDocumentAction: history->sendActions.insert(user, SendAction(SendActionUploadFile, ms + 6000, action.c_sendMessageUploadDocumentAction().vprogress.v)); break; + case mtpc_sendMessageGeoLocationAction: history->sendActions.insert(user, SendAction(SendActionChooseLocation, ms + 6000)); break; + case mtpc_sendMessageChooseContactAction: history->sendActions.insert(user, SendAction(SendActionChooseContact, ms + 6000)); break; + default: return; + } user->madeAction(); @@ -530,7 +564,7 @@ bool Histories::animStep(float64) { App::main()->dlgUpdated(i.key()); App::main()->topBar()->update(); } - if (i.key()->typing.isEmpty()) { + if (i.key()->typing.isEmpty() && i.key()->sendActions.isEmpty()) { i = typing.erase(i); } else { ++i; @@ -943,11 +977,22 @@ HistoryItem *History::doAddToBack(HistoryBlock *to, bool newBlock, HistoryItem * } void History::unregTyping(UserData *from) { + bool update = false; + uint64 updateAtMs = 0; TypingUsers::iterator i = typing.find(from); if (i != typing.end()) { - uint64 ms = getms(true); - i.value() = ms; - updateTyping(ms, 0, true); + updateAtMs = getms(true); + i.value() = updateAtMs; + update = true; + } + SendActionUsers::iterator j = sendActions.find(from); + if (j != sendActions.end()) { + if (!updateAtMs) updateAtMs = getms(true); + j.value().until = updateAtMs; + update = true; + } + if (updateAtMs) { + updateTyping(updateAtMs, 0, true); App::main()->topBar()->update(); } } diff --git a/Telegram/SourceFiles/history.h b/Telegram/SourceFiles/history.h index 0c92dcc6fb..9e4a0810f4 100644 --- a/Telegram/SourceFiles/history.h +++ b/Telegram/SourceFiles/history.h @@ -41,7 +41,7 @@ struct Histories : public QHash, public Animated { Histories() : unreadFull(0), unreadMuted(0) { } - void regTyping(History *history, UserData *user); + void regSendAction(History *history, UserData *user, const MTPSendMessageAction &action); bool animStep(float64 ms); void clear(); @@ -134,6 +134,25 @@ inline MTPMessagesFilter typeToMediaFilter(MediaOverviewType &type) { return MTPMessagesFilter(); } +enum SendActionType { + SendActionTyping, + SendActionRecordVideo, + SendActionUploadVideo, + SendActionRecordAudio, + SendActionUploadAudio, + SendActionUploadPhoto, + SendActionUploadFile, + SendActionChooseLocation, + SendActionChooseContact, +}; +struct SendAction { + SendAction(SendActionType type, uint64 until, int32 progress = 0) : type(type), until(until), progress(progress) { + } + SendActionType type; + uint64 until; + int32 progress; +}; + class HistoryMedia; class HistoryMessage; class HistoryUnreadBar; @@ -273,11 +292,13 @@ struct History : public QList { typedef QMap TypingUsers; TypingUsers typing; + typedef QMap SendActionUsers; + SendActionUsers sendActions; QString typingStr; Text typingText; uint32 typingFrame; bool updateTyping(uint64 ms = 0, uint32 dots = 0, bool force = false); - uint64 myTyping; + QMap mySendActions; typedef QList MediaOverview; typedef QMap MediaOverviewIds; diff --git a/Telegram/SourceFiles/historywidget.cpp b/Telegram/SourceFiles/historywidget.cpp index ec14a0d7ec..35c3f18a92 100644 --- a/Telegram/SourceFiles/historywidget.cpp +++ b/Telegram/SourceFiles/historywidget.cpp @@ -2233,7 +2233,6 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent) , _titlePeerTextWidth(0) , _showAnim(animFunc(this, &HistoryWidget::showStep)) , _scrollDelta(0) -, _typingRequest(0) , _saveDraftStart(0) , _saveDraftText(false) { _scroll.setFocusPolicy(Qt::NoFocus); @@ -2262,7 +2261,7 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent) connect(&_emojiPan, SIGNAL(emojiSelected(EmojiPtr)), &_field, SLOT(onEmojiInsert(EmojiPtr))); connect(&_emojiPan, SIGNAL(stickerSelected(DocumentData*)), this, SLOT(onStickerSend(DocumentData*))); connect(&_emojiPan, SIGNAL(updateStickers()), this, SLOT(updateStickers())); - connect(&_typingStopTimer, SIGNAL(timeout()), this, SLOT(cancelTyping())); + connect(&_sendActionStopTimer, SIGNAL(timeout()), this, SLOT(onCancelSendAction())); connect(&_previewTimer, SIGNAL(timeout()), this, SLOT(onPreviewTimeout())); if (audioCapture()) { connect(audioCapture(), SIGNAL(onError()), this, SLOT(onRecordError())); @@ -2272,7 +2271,7 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent) _scrollTimer.setSingleShot(false); - _typingStopTimer.setSingleShot(true); + _sendActionStopTimer.setSingleShot(true); _animActiveTimer.setSingleShot(false); connect(&_animActiveTimer, SIGNAL(timeout()), this, SLOT(onAnimActiveStep())); @@ -2350,7 +2349,7 @@ void HistoryWidget::onMentionHashtagOrBotCommandInsert(QString str) { } void HistoryWidget::onTextChange() { - updateTyping(); + updateSendAction(_history, SendActionTyping); if (cHasAudioCapture()) { if (_field.getLastText().isEmpty() && !App::main()->hasForwardingItems()) { @@ -2369,8 +2368,8 @@ void HistoryWidget::onTextChange() { } if (updateCmdStartShown()) { updateControlsVisibility(); - resizeEvent(0); - update(); +resizeEvent(0); +update(); } if (!_history || _synthedTextUpdate) return; @@ -2411,22 +2410,55 @@ void HistoryWidget::writeDraft(MsgId *replyTo, const QString *text, const Messag if (save) Local::writeDraftPositions(_history->peer->id, cursor ? (*cursor) : MessageCursor(_field)); } -void HistoryWidget::cancelTyping() { - if (_typingRequest) { - MTP::cancel(_typingRequest); - _typingRequest = 0; +void HistoryWidget::cancelSendAction(History *history, SendActionType type) { + QMap, mtpRequestId>::iterator i = _sendActionRequests.find(qMakePair(history, type)); + if (i != _sendActionRequests.cend()) { + MTP::cancel(i.value()); + _sendActionRequests.erase(i); } } -void HistoryWidget::updateTyping(bool typing) { - uint64 ms = getms(true) + 10000; - if (_synthedTextUpdate || !_history || (typing && (_history->myTyping + 5000 > ms)) || (!typing && (_history->myTyping + 5000 <= ms))) return; +void HistoryWidget::onCancelSendAction() { + cancelSendAction(_history, SendActionTyping); +} - _history->myTyping = typing ? ms : 0; - cancelTyping(); - if (typing) { - _typingRequest = MTP::send(MTPmessages_SetTyping(_peer->input, typing ? MTP_sendMessageTypingAction() : MTP_sendMessageCancelAction()), rpcDone(&HistoryWidget::typingDone)); - _typingStopTimer.start(5000); +void HistoryWidget::updateSendAction(History *history, SendActionType type, int32 progress) { + if (!history) return; + if (type == SendActionTyping && _synthedTextUpdate) return; + + bool doing = (progress >= 0); + + uint64 ms = getms(true) + 10000; + QMap::iterator i = history->mySendActions.find(type); + if (doing && i != history->mySendActions.cend() && i.value() + 5000 > ms) return; + if (!doing && (i == history->mySendActions.cend() || i.value() + 5000 <= ms)) return; + + if (doing) { + if (i == history->mySendActions.cend()) { + history->mySendActions.insert(type, ms); + } else { + i.value() = ms; + } + } else if (i != history->mySendActions.cend()) { + history->mySendActions.erase(i); + } + + cancelSendAction(history, type); + if (doing) { + MTPsendMessageAction action; + switch (type) { + case SendActionTyping: action = MTP_sendMessageTypingAction(); break; + case SendActionRecordVideo: action = MTP_sendMessageRecordVideoAction(); break; + case SendActionUploadVideo: action = MTP_sendMessageUploadVideoAction(MTP_int(progress)); break; + case SendActionRecordAudio: action = MTP_sendMessageRecordAudioAction(); break; + case SendActionUploadAudio: action = MTP_sendMessageUploadAudioAction(MTP_int(progress)); break; + case SendActionUploadPhoto: action = MTP_sendMessageUploadPhotoAction(MTP_int(progress)); break; + case SendActionUploadFile: action = MTP_sendMessageUploadDocumentAction(MTP_int(progress)); break; + case SendActionChooseLocation: action = MTP_sendMessageGeoLocationAction(); break; + case SendActionChooseContact: action = MTP_sendMessageChooseContactAction(); break; + } + _sendActionRequests.insert(qMakePair(history, type), MTP::send(MTPmessages_SetTyping(_peer->input, action), rpcDone(&HistoryWidget::sendActionDone))); + if (type == SendActionTyping) _sendActionStopTimer.start(5000); } } @@ -2438,9 +2470,12 @@ void HistoryWidget::stickersInstalled(uint64 setId) { _emojiPan.stickersInstalled(setId); } -void HistoryWidget::typingDone(const MTPBool &result, mtpRequestId req) { - if (_typingRequest == req) { - _typingRequest = 0; +void HistoryWidget::sendActionDone(const MTPBool &result, mtpRequestId req) { + for (QMap, mtpRequestId>::iterator i = _sendActionRequests.begin(), e = _sendActionRequests.end(); i != e; ++i) { + if (i.value() == req) { + _sendActionRequests.erase(i); + break; + } } } @@ -2480,6 +2515,7 @@ void HistoryWidget::onRecordUpdate(qint16 level, qint32 samples) { stopRecording(_peer && samples > 0 && _inField); } updateField(); + updateSendAction(_history, SendActionRecordAudio); } void HistoryWidget::updateStickers() { @@ -2688,7 +2724,7 @@ void HistoryWidget::showPeerHistory(const PeerId &peerId, MsgId showAtMsgId) { update(); return; } - updateTyping(false); + if (_history->mySendActions.contains(SendActionTyping)) updateSendAction(_history, SendActionTyping, false); } stopGif(); @@ -3602,6 +3638,8 @@ void HistoryWidget::stopRecording(bool send) { _recording = false; _recordingSamples = 0; + updateSendAction(_history, SendActionRecordAudio, -1); + updateControlsVisibility(); activate(); @@ -3922,7 +3960,7 @@ void HistoryWidget::paintTopBar(QPainter &p, float64 over, int32 decreaseWidth) decreaseWidth += increaseLeft; QRect rectForName(st::topBarForwardPadding.left() + increaseLeft, st::topBarForwardPadding.top(), width() - decreaseWidth - st::topBarForwardPadding.left() - st::topBarForwardPadding.right(), st::msgNameFont->height); p.setFont(st::dlgHistFont->f); - if (_history->typing.isEmpty()) { + if (_history->typing.isEmpty() && _history->sendActions.isEmpty()) { p.setPen(st::titleStatusColor->p); p.drawText(rectForName.x(), st::topBarHeight - st::topBarForwardPadding.bottom() - st::dlgHistFont->height + st::dlgHistFont->ascent, _titlePeerText); } else { @@ -4188,10 +4226,10 @@ void HistoryWidget::confirmSendImage(const ReadyLocalMedia &img) { connect(App::uploader(), SIGNAL(documentReady(MsgId, const MTPInputFile &)), this, SLOT(onDocumentUploaded(MsgId, const MTPInputFile &)), Qt::UniqueConnection); connect(App::uploader(), SIGNAL(thumbDocumentReady(MsgId, const MTPInputFile &, const MTPInputFile &)), this, SLOT(onThumbDocumentUploaded(MsgId, const MTPInputFile &, const MTPInputFile &)), Qt::UniqueConnection); connect(App::uploader(), SIGNAL(audioReady(MsgId, const MTPInputFile &)), this, SLOT(onAudioUploaded(MsgId, const MTPInputFile &)), Qt::UniqueConnection); -// connect(App::uploader(), SIGNAL(photoProgress(MsgId)), this, SLOT(onPhotoProgress(MsgId)), Qt::UniqueConnection); + connect(App::uploader(), SIGNAL(photoProgress(MsgId)), this, SLOT(onPhotoProgress(MsgId)), Qt::UniqueConnection); connect(App::uploader(), SIGNAL(documentProgress(MsgId)), this, SLOT(onDocumentProgress(MsgId)), Qt::UniqueConnection); connect(App::uploader(), SIGNAL(audioProgress(MsgId)), this, SLOT(onAudioProgress(MsgId)), Qt::UniqueConnection); -// connect(App::uploader(), SIGNAL(photoFailed(MsgId)), this, SLOT(onPhotoFailed(MsgId)), Qt::UniqueConnection); + connect(App::uploader(), SIGNAL(photoFailed(MsgId)), this, SLOT(onPhotoFailed(MsgId)), Qt::UniqueConnection); connect(App::uploader(), SIGNAL(documentFailed(MsgId)), this, SLOT(onDocumentFailed(MsgId)), Qt::UniqueConnection); connect(App::uploader(), SIGNAL(audioFailed(MsgId)), this, SLOT(onAudioFailed(MsgId)), Qt::UniqueConnection); @@ -4328,10 +4366,22 @@ void HistoryWidget::onAudioUploaded(MsgId newId, const MTPInputFile &file) { } } +void HistoryWidget::onPhotoProgress(MsgId newId) { + if (!MTP::authedId()) return; + HistoryItem *item = App::histItemById(newId); + if (item) { + PhotoData *photo = (item->getMedia() && item->getMedia()->type() == MediaTypePhoto) ? static_cast(item->getMedia())->photo() : 0; + updateSendAction(item->history(), SendActionUploadPhoto, 0); +// msgUpdated(item->history()->peer->id, item); + } +} + void HistoryWidget::onDocumentProgress(MsgId newId) { if (!MTP::authedId()) return; HistoryItem *item = App::histItemById(newId); if (item) { + DocumentData *doc = (item->getMedia() && item->getMedia()->type() == MediaTypeDocument) ? static_cast(item->getMedia())->document() : 0; + updateSendAction(item->history(), SendActionUploadFile, doc->uploadOffset); msgUpdated(item->history()->peer->id, item); } } @@ -4340,14 +4390,26 @@ void HistoryWidget::onAudioProgress(MsgId newId) { if (!MTP::authedId()) return; HistoryItem *item = App::histItemById(newId); if (item) { + AudioData *audio = (item->getMedia() && item->getMedia()->type() == MediaTypeAudio) ? static_cast(item->getMedia())->audio() : 0; + updateSendAction(item->history(), SendActionUploadAudio, audio->uploadOffset); msgUpdated(item->history()->peer->id, item); } } +void HistoryWidget::onPhotoFailed(MsgId newId) { + if (!MTP::authedId()) return; + HistoryItem *item = App::histItemById(newId); + if (item) { + updateSendAction(item->history(), SendActionUploadPhoto, -1); +// msgUpdated(item->history()->peer->id, item); + } +} + void HistoryWidget::onDocumentFailed(MsgId newId) { if (!MTP::authedId()) return; HistoryItem *item = App::histItemById(newId); if (item) { + updateSendAction(item->history(), SendActionUploadFile, -1); msgUpdated(item->history()->peer->id, item); } } @@ -4356,6 +4418,7 @@ void HistoryWidget::onAudioFailed(MsgId newId) { if (!MTP::authedId()) return; HistoryItem *item = App::histItemById(newId); if (item) { + updateSendAction(item->history(), SendActionUploadAudio, -1); msgUpdated(item->history()->peer->id, item); } } diff --git a/Telegram/SourceFiles/historywidget.h b/Telegram/SourceFiles/historywidget.h index 32cab7e05a..e6535ccfed 100644 --- a/Telegram/SourceFiles/historywidget.h +++ b/Telegram/SourceFiles/historywidget.h @@ -386,10 +386,12 @@ public: QRect historyRect() const; - void updateTyping(bool typing = true); + void updateSendAction(History *history, SendActionType type, int32 progress = 0); + void cancelSendAction(History *history, SendActionType type); + void updateRecentStickers(); void stickersInstalled(uint64 setId); - void typingDone(const MTPBool &result, mtpRequestId req); + void sendActionDone(const MTPBool &result, mtpRequestId req); void destroyData(); void uploadImage(const QImage &img, bool withText = false, const QString &source = QString()); @@ -489,6 +491,8 @@ public slots: void onReplyToMessage(); void onReplyForwardPreviewCancel(); + void onCancelSendAction(); + void onStickerPackInfo(); void onPreviewParse(); @@ -498,16 +502,16 @@ public slots: void peerUpdated(PeerData *data); void onFullPeerUpdated(PeerData *data); - void cancelTyping(); - void onPhotoUploaded(MsgId msgId, const MTPInputFile &file); void onDocumentUploaded(MsgId msgId, const MTPInputFile &file); void onThumbDocumentUploaded(MsgId msgId, const MTPInputFile &file, const MTPInputFile &thumb); void onAudioUploaded(MsgId msgId, const MTPInputFile &file); + void onPhotoProgress(MsgId msgId); void onDocumentProgress(MsgId msgId); void onAudioProgress(MsgId msgId); + void onPhotoFailed(MsgId msgId); void onDocumentFailed(MsgId msgId); void onAudioFailed(MsgId msgId); @@ -685,8 +689,8 @@ private: QTimer _animActiveTimer; float64 _animActiveStart; - mtpRequestId _typingRequest; - QTimer _typingStopTimer; + QMap, mtpRequestId> _sendActionRequests; + QTimer _sendActionStopTimer; uint64 _saveDraftStart; bool _saveDraftText; diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index 9efbe53964..b56c882b78 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -3483,11 +3483,7 @@ void MainWidget::feedUpdate(const MTPUpdate &update) { History *history = App::historyLoaded(App::peerFromUser(d.vuser_id)); UserData *user = App::userLoaded(d.vuser_id.v); if (history && user) { - if (d.vaction.type() == mtpc_sendMessageTypingAction) { - App::histories().regTyping(history, user); - } else if (d.vaction.type() == mtpc_sendMessageCancelAction) { - history->unregTyping(user); - } + App::histories().regSendAction(history, user, d.vaction); } } break; @@ -3496,7 +3492,7 @@ void MainWidget::feedUpdate(const MTPUpdate &update) { History *history = App::historyLoaded(App::peerFromChat(d.vchat_id)); UserData *user = (d.vuser_id.v == MTP::authedId()) ? 0 : App::userLoaded(d.vuser_id.v); if (history && user) { - App::histories().regTyping(history, user); + App::histories().regSendAction(history, user, d.vaction); } } break; diff --git a/Telegram/Telegram.plist b/Telegram/Telegram.plist index e135655420..9b636481c2 100644 --- a/Telegram/Telegram.plist +++ b/Telegram/Telegram.plist @@ -11,7 +11,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 0.8.43 + 0.8.44 LSMinimumSystemVersion $(MACOSX_DEPLOYMENT_TARGET) CFBundleSignature diff --git a/Telegram/Telegram.rc b/Telegram/Telegram.rc index e61aa8e03c..9192bbd0a8 100644 Binary files a/Telegram/Telegram.rc and b/Telegram/Telegram.rc differ diff --git a/Telegram/Telegram.xcodeproj/project.pbxproj b/Telegram/Telegram.xcodeproj/project.pbxproj index af3c1dec28..414a38097d 100644 --- a/Telegram/Telegram.xcodeproj/project.pbxproj +++ b/Telegram/Telegram.xcodeproj/project.pbxproj @@ -1707,7 +1707,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 0.8.43; + CURRENT_PROJECT_VERSION = 0.8.44; DEBUG_INFORMATION_FORMAT = dwarf; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; @@ -1725,7 +1725,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; COPY_PHASE_STRIP = YES; - CURRENT_PROJECT_VERSION = 0.8.43; + CURRENT_PROJECT_VERSION = 0.8.44; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_OPTIMIZATION_LEVEL = fast; GCC_PREFIX_HEADER = ./SourceFiles/stdafx.h; @@ -1751,10 +1751,10 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = ""; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 0.8.43; + CURRENT_PROJECT_VERSION = 0.8.44; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DYLIB_COMPATIBILITY_VERSION = 0.8; - DYLIB_CURRENT_VERSION = 0.8.43; + DYLIB_CURRENT_VERSION = 0.8.44; ENABLE_STRICT_OBJC_MSGSEND = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; @@ -1885,10 +1885,10 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = ""; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 0.8.43; + CURRENT_PROJECT_VERSION = 0.8.44; DEBUG_INFORMATION_FORMAT = dwarf; DYLIB_COMPATIBILITY_VERSION = 0.8; - DYLIB_CURRENT_VERSION = 0.8.43; + DYLIB_CURRENT_VERSION = 0.8.44; ENABLE_STRICT_OBJC_MSGSEND = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; diff --git a/Telegram/Version.sh b/Telegram/Version.sh index b370f5f6ab..3dcc3a6b34 100755 --- a/Telegram/Version.sh +++ b/Telegram/Version.sh @@ -1,2 +1,2 @@ -echo 0.8 8043 0.8.43 0 +echo 0.8 8044 0.8.44 1 # AppVersionStrMajor AppVersion AppVersionStr DevChannel