0.8.44 dev version - media typings support

This commit is contained in:
John Preston 2015-08-01 11:33:00 +03:00
parent ab23ef4c4f
commit 86325e889f
14 changed files with 212 additions and 66 deletions

View File

@ -1,11 +1,11 @@
@echo OFF @echo OFF
set "AppVersionStrMajor=0.8" set "AppVersionStrMajor=0.8"
set "AppVersion=8043" set "AppVersion=8044"
set "AppVersionStrSmall=0.8.43" set "AppVersionStrSmall=0.8.44"
set "AppVersionStr=0.8.43" set "AppVersionStr=0.8.44"
set "AppVersionStrFull=0.8.43.0" set "AppVersionStrFull=0.8.44.0"
set "DevChannel=0" set "DevChannel=1"
if %DevChannel% neq 0 goto preparedev if %DevChannel% neq 0 goto preparedev

View File

@ -478,6 +478,22 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
"lng_user_typing" = "{user} is typing"; "lng_user_typing" = "{user} is typing";
"lng_users_typing" = "{user} and {second_user} are typing"; "lng_users_typing" = "{user} and {second_user} are typing";
"lng_many_typing" = "{count:_not_used_|# is|# 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_unread_bar" = "{count:_not_used_|# unread message|# unread messages}";
"lng_maps_point" = "Location"; "lng_maps_point" = "Location";

View File

@ -658,8 +658,8 @@ void Application::checkMapVersion() {
psRegisterCustomScheme(); psRegisterCustomScheme();
if (Local::oldMapVersion()) { if (Local::oldMapVersion()) {
QString versionFeatures; QString versionFeatures;
if (cDevVersion() && Local::oldMapVersion() < 8042) { if (cDevVersion() && Local::oldMapVersion() < 8044) {
versionFeatures = QString::fromUtf8("\xe2\x80\x94 Dev version will now get updated to stable as well");// .replace('@', qsl("@") + QChar(0x200D)); versionFeatures = QString::fromUtf8("\xe2\x80\x94 Sending media and recording audio status display");// .replace('@', qsl("@") + QChar(0x200D));
} else if (!cDevVersion() && Local::oldMapVersion() < 8043) { } else if (!cDevVersion() && Local::oldMapVersion() < 8043) {
versionFeatures = lang(lng_new_version_minor).trimmed(); versionFeatures = lang(lng_new_version_minor).trimmed();
} }

View File

@ -17,9 +17,9 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
*/ */
#pragma once #pragma once
static const int32 AppVersion = 8043; static const int32 AppVersion = 8044;
static const wchar_t *AppVersionStr = L"0.8.43"; static const wchar_t *AppVersionStr = L"0.8.44";
static const bool DevVersion = false; static const bool DevVersion = true;
static const wchar_t *AppNameOld = L"Telegram Win (Unofficial)"; static const wchar_t *AppNameOld = L"Telegram Win (Unofficial)";
static const wchar_t *AppName = L"Telegram Desktop"; static const wchar_t *AppName = L"Telegram Desktop";

View File

@ -273,6 +273,7 @@ void FileUploader::partLoaded(const MTPBool &result, mtpRequestId requestId) {
audio->uploadOffset = audio->size; audio->uploadOffset = audio->size;
} }
} }
emit audioProgress(k.key());
} }
} }
} }

View File

@ -167,7 +167,7 @@ void DialogRow::paint(QPainter &p, int32 w, bool act, bool sel) const {
if (!last) { if (!last) {
p.setFont(st::dlgHistFont->f); p.setFont(st::dlgHistFont->f);
p.setPen((act ? st::dlgActiveColor : st::dlgSystemColor)->p); 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)); p.drawText(nameleft, st::dlgPaddingVer + st::dlgFont->height + st::dlgFont->ascent + st::dlgSep, lang(lng_empty_history));
} else { } else {
history->typingText.drawElided(p, nameleft, st::dlgPaddingVer + st::dlgFont->height + st::dlgSep, namewidth); 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.setPen((act ? st::dlgActiveUnreadColor : st::dlgUnreadColor)->p);
p.drawText(unreadRectLeft + st::dlgUnreadPaddingHor, unreadRectTop + st::dlgUnreadPaddingVer + st::dlgUnreadFont->ascent, unreadStr); 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); last->drawInDialog(p, QRect(nameleft, st::dlgPaddingVer + st::dlgFont->height + st::dlgSep, lastWidth, st::dlgFont->height), act, history->textCachedFor, history->lastItemTextCache);
} else { } else {
p.setPen((act ? st::dlgActiveColor : st::dlgSystemColor)->p); p.setPen((act ? st::dlgActiveColor : st::dlgSystemColor)->p);
@ -319,7 +319,6 @@ History::History(const PeerId &peerId) : width(0), height(0)
, lastItemTextCache(st::dlgRichMinWidth) , lastItemTextCache(st::dlgRichMinWidth)
, posInDialogs(0) , posInDialogs(0)
, typingText(st::dlgRichMinWidth) , typingText(st::dlgRichMinWidth)
, myTyping(0)
{ {
for (int32 i = 0; i < OverviewCount; ++i) { for (int32 i = 0; i < OverviewCount; ++i) {
_overviewCount[i] = -1; // not loaded yet _overviewCount[i] = -1; // not loaded yet
@ -347,6 +346,14 @@ bool History::updateTyping(uint64 ms, uint32 dots, bool force) {
++i; ++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) { if (changed) {
QString newTypingStr; QString newTypingStr;
int32 cnt = typing.size(); 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); newTypingStr = lng_users_typing(lt_user, typing.begin().key()->firstName, lt_second_user, (typing.end() - 1).key()->firstName);
} else if (cnt) { } else if (cnt) {
newTypingStr = peer->chat ? lng_user_typing(lt_user, typing.begin().key()->firstName) : lang(lng_typing); 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()) { if (!newTypingStr.isEmpty()) {
newTypingStr += qsl("..."); newTypingStr += qsl("...");
@ -506,9 +524,25 @@ void Histories::clear() {
Parent::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); 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(); user->madeAction();
@ -530,7 +564,7 @@ bool Histories::animStep(float64) {
App::main()->dlgUpdated(i.key()); App::main()->dlgUpdated(i.key());
App::main()->topBar()->update(); App::main()->topBar()->update();
} }
if (i.key()->typing.isEmpty()) { if (i.key()->typing.isEmpty() && i.key()->sendActions.isEmpty()) {
i = typing.erase(i); i = typing.erase(i);
} else { } else {
++i; ++i;
@ -943,11 +977,22 @@ HistoryItem *History::doAddToBack(HistoryBlock *to, bool newBlock, HistoryItem *
} }
void History::unregTyping(UserData *from) { void History::unregTyping(UserData *from) {
bool update = false;
uint64 updateAtMs = 0;
TypingUsers::iterator i = typing.find(from); TypingUsers::iterator i = typing.find(from);
if (i != typing.end()) { if (i != typing.end()) {
uint64 ms = getms(true); updateAtMs = getms(true);
i.value() = ms; i.value() = updateAtMs;
updateTyping(ms, 0, true); 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(); App::main()->topBar()->update();
} }
} }

View File

@ -41,7 +41,7 @@ struct Histories : public QHash<PeerId, History*>, public Animated {
Histories() : unreadFull(0), unreadMuted(0) { Histories() : unreadFull(0), unreadMuted(0) {
} }
void regTyping(History *history, UserData *user); void regSendAction(History *history, UserData *user, const MTPSendMessageAction &action);
bool animStep(float64 ms); bool animStep(float64 ms);
void clear(); void clear();
@ -134,6 +134,25 @@ inline MTPMessagesFilter typeToMediaFilter(MediaOverviewType &type) {
return MTPMessagesFilter(); 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 HistoryMedia;
class HistoryMessage; class HistoryMessage;
class HistoryUnreadBar; class HistoryUnreadBar;
@ -273,11 +292,13 @@ struct History : public QList<HistoryBlock*> {
typedef QMap<UserData*, uint64> TypingUsers; typedef QMap<UserData*, uint64> TypingUsers;
TypingUsers typing; TypingUsers typing;
typedef QMap<UserData*, SendAction> SendActionUsers;
SendActionUsers sendActions;
QString typingStr; QString typingStr;
Text typingText; Text typingText;
uint32 typingFrame; uint32 typingFrame;
bool updateTyping(uint64 ms = 0, uint32 dots = 0, bool force = false); bool updateTyping(uint64 ms = 0, uint32 dots = 0, bool force = false);
uint64 myTyping; QMap<SendActionType, uint64> mySendActions;
typedef QList<MsgId> MediaOverview; typedef QList<MsgId> MediaOverview;
typedef QMap<MsgId, NullType> MediaOverviewIds; typedef QMap<MsgId, NullType> MediaOverviewIds;

View File

@ -2233,7 +2233,6 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent)
, _titlePeerTextWidth(0) , _titlePeerTextWidth(0)
, _showAnim(animFunc(this, &HistoryWidget::showStep)) , _showAnim(animFunc(this, &HistoryWidget::showStep))
, _scrollDelta(0) , _scrollDelta(0)
, _typingRequest(0)
, _saveDraftStart(0) , _saveDraftStart(0)
, _saveDraftText(false) { , _saveDraftText(false) {
_scroll.setFocusPolicy(Qt::NoFocus); _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(emojiSelected(EmojiPtr)), &_field, SLOT(onEmojiInsert(EmojiPtr)));
connect(&_emojiPan, SIGNAL(stickerSelected(DocumentData*)), this, SLOT(onStickerSend(DocumentData*))); connect(&_emojiPan, SIGNAL(stickerSelected(DocumentData*)), this, SLOT(onStickerSend(DocumentData*)));
connect(&_emojiPan, SIGNAL(updateStickers()), this, SLOT(updateStickers())); 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())); connect(&_previewTimer, SIGNAL(timeout()), this, SLOT(onPreviewTimeout()));
if (audioCapture()) { if (audioCapture()) {
connect(audioCapture(), SIGNAL(onError()), this, SLOT(onRecordError())); connect(audioCapture(), SIGNAL(onError()), this, SLOT(onRecordError()));
@ -2272,7 +2271,7 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent)
_scrollTimer.setSingleShot(false); _scrollTimer.setSingleShot(false);
_typingStopTimer.setSingleShot(true); _sendActionStopTimer.setSingleShot(true);
_animActiveTimer.setSingleShot(false); _animActiveTimer.setSingleShot(false);
connect(&_animActiveTimer, SIGNAL(timeout()), this, SLOT(onAnimActiveStep())); connect(&_animActiveTimer, SIGNAL(timeout()), this, SLOT(onAnimActiveStep()));
@ -2350,7 +2349,7 @@ void HistoryWidget::onMentionHashtagOrBotCommandInsert(QString str) {
} }
void HistoryWidget::onTextChange() { void HistoryWidget::onTextChange() {
updateTyping(); updateSendAction(_history, SendActionTyping);
if (cHasAudioCapture()) { if (cHasAudioCapture()) {
if (_field.getLastText().isEmpty() && !App::main()->hasForwardingItems()) { if (_field.getLastText().isEmpty() && !App::main()->hasForwardingItems()) {
@ -2369,8 +2368,8 @@ void HistoryWidget::onTextChange() {
} }
if (updateCmdStartShown()) { if (updateCmdStartShown()) {
updateControlsVisibility(); updateControlsVisibility();
resizeEvent(0); resizeEvent(0);
update(); update();
} }
if (!_history || _synthedTextUpdate) return; 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)); if (save) Local::writeDraftPositions(_history->peer->id, cursor ? (*cursor) : MessageCursor(_field));
} }
void HistoryWidget::cancelTyping() { void HistoryWidget::cancelSendAction(History *history, SendActionType type) {
if (_typingRequest) { QMap<QPair<History*, SendActionType>, mtpRequestId>::iterator i = _sendActionRequests.find(qMakePair(history, type));
MTP::cancel(_typingRequest); if (i != _sendActionRequests.cend()) {
_typingRequest = 0; MTP::cancel(i.value());
_sendActionRequests.erase(i);
} }
} }
void HistoryWidget::updateTyping(bool typing) { void HistoryWidget::onCancelSendAction() {
uint64 ms = getms(true) + 10000; cancelSendAction(_history, SendActionTyping);
if (_synthedTextUpdate || !_history || (typing && (_history->myTyping + 5000 > ms)) || (!typing && (_history->myTyping + 5000 <= ms))) return; }
_history->myTyping = typing ? ms : 0; void HistoryWidget::updateSendAction(History *history, SendActionType type, int32 progress) {
cancelTyping(); if (!history) return;
if (typing) { if (type == SendActionTyping && _synthedTextUpdate) return;
_typingRequest = MTP::send(MTPmessages_SetTyping(_peer->input, typing ? MTP_sendMessageTypingAction() : MTP_sendMessageCancelAction()), rpcDone(&HistoryWidget::typingDone));
_typingStopTimer.start(5000); bool doing = (progress >= 0);
uint64 ms = getms(true) + 10000;
QMap<SendActionType, uint64>::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); _emojiPan.stickersInstalled(setId);
} }
void HistoryWidget::typingDone(const MTPBool &result, mtpRequestId req) { void HistoryWidget::sendActionDone(const MTPBool &result, mtpRequestId req) {
if (_typingRequest == req) { for (QMap<QPair<History*, SendActionType>, mtpRequestId>::iterator i = _sendActionRequests.begin(), e = _sendActionRequests.end(); i != e; ++i) {
_typingRequest = 0; if (i.value() == req) {
_sendActionRequests.erase(i);
break;
}
} }
} }
@ -2480,6 +2515,7 @@ void HistoryWidget::onRecordUpdate(qint16 level, qint32 samples) {
stopRecording(_peer && samples > 0 && _inField); stopRecording(_peer && samples > 0 && _inField);
} }
updateField(); updateField();
updateSendAction(_history, SendActionRecordAudio);
} }
void HistoryWidget::updateStickers() { void HistoryWidget::updateStickers() {
@ -2688,7 +2724,7 @@ void HistoryWidget::showPeerHistory(const PeerId &peerId, MsgId showAtMsgId) {
update(); update();
return; return;
} }
updateTyping(false); if (_history->mySendActions.contains(SendActionTyping)) updateSendAction(_history, SendActionTyping, false);
} }
stopGif(); stopGif();
@ -3602,6 +3638,8 @@ void HistoryWidget::stopRecording(bool send) {
_recording = false; _recording = false;
_recordingSamples = 0; _recordingSamples = 0;
updateSendAction(_history, SendActionRecordAudio, -1);
updateControlsVisibility(); updateControlsVisibility();
activate(); activate();
@ -3922,7 +3960,7 @@ void HistoryWidget::paintTopBar(QPainter &p, float64 over, int32 decreaseWidth)
decreaseWidth += increaseLeft; decreaseWidth += increaseLeft;
QRect rectForName(st::topBarForwardPadding.left() + increaseLeft, st::topBarForwardPadding.top(), width() - decreaseWidth - st::topBarForwardPadding.left() - st::topBarForwardPadding.right(), st::msgNameFont->height); 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); p.setFont(st::dlgHistFont->f);
if (_history->typing.isEmpty()) { if (_history->typing.isEmpty() && _history->sendActions.isEmpty()) {
p.setPen(st::titleStatusColor->p); p.setPen(st::titleStatusColor->p);
p.drawText(rectForName.x(), st::topBarHeight - st::topBarForwardPadding.bottom() - st::dlgHistFont->height + st::dlgHistFont->ascent, _titlePeerText); p.drawText(rectForName.x(), st::topBarHeight - st::topBarForwardPadding.bottom() - st::dlgHistFont->height + st::dlgHistFont->ascent, _titlePeerText);
} else { } 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(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(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(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(documentProgress(MsgId)), this, SLOT(onDocumentProgress(MsgId)), Qt::UniqueConnection);
connect(App::uploader(), SIGNAL(audioProgress(MsgId)), this, SLOT(onAudioProgress(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(documentFailed(MsgId)), this, SLOT(onDocumentFailed(MsgId)), Qt::UniqueConnection);
connect(App::uploader(), SIGNAL(audioFailed(MsgId)), this, SLOT(onAudioFailed(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<HistoryPhoto*>(item->getMedia())->photo() : 0;
updateSendAction(item->history(), SendActionUploadPhoto, 0);
// msgUpdated(item->history()->peer->id, item);
}
}
void HistoryWidget::onDocumentProgress(MsgId newId) { void HistoryWidget::onDocumentProgress(MsgId newId) {
if (!MTP::authedId()) return; if (!MTP::authedId()) return;
HistoryItem *item = App::histItemById(newId); HistoryItem *item = App::histItemById(newId);
if (item) { if (item) {
DocumentData *doc = (item->getMedia() && item->getMedia()->type() == MediaTypeDocument) ? static_cast<HistoryDocument*>(item->getMedia())->document() : 0;
updateSendAction(item->history(), SendActionUploadFile, doc->uploadOffset);
msgUpdated(item->history()->peer->id, item); msgUpdated(item->history()->peer->id, item);
} }
} }
@ -4340,14 +4390,26 @@ void HistoryWidget::onAudioProgress(MsgId newId) {
if (!MTP::authedId()) return; if (!MTP::authedId()) return;
HistoryItem *item = App::histItemById(newId); HistoryItem *item = App::histItemById(newId);
if (item) { if (item) {
AudioData *audio = (item->getMedia() && item->getMedia()->type() == MediaTypeAudio) ? static_cast<HistoryAudio*>(item->getMedia())->audio() : 0;
updateSendAction(item->history(), SendActionUploadAudio, audio->uploadOffset);
msgUpdated(item->history()->peer->id, item); 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) { void HistoryWidget::onDocumentFailed(MsgId newId) {
if (!MTP::authedId()) return; if (!MTP::authedId()) return;
HistoryItem *item = App::histItemById(newId); HistoryItem *item = App::histItemById(newId);
if (item) { if (item) {
updateSendAction(item->history(), SendActionUploadFile, -1);
msgUpdated(item->history()->peer->id, item); msgUpdated(item->history()->peer->id, item);
} }
} }
@ -4356,6 +4418,7 @@ void HistoryWidget::onAudioFailed(MsgId newId) {
if (!MTP::authedId()) return; if (!MTP::authedId()) return;
HistoryItem *item = App::histItemById(newId); HistoryItem *item = App::histItemById(newId);
if (item) { if (item) {
updateSendAction(item->history(), SendActionUploadAudio, -1);
msgUpdated(item->history()->peer->id, item); msgUpdated(item->history()->peer->id, item);
} }
} }

View File

@ -386,10 +386,12 @@ public:
QRect historyRect() const; 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 updateRecentStickers();
void stickersInstalled(uint64 setId); void stickersInstalled(uint64 setId);
void typingDone(const MTPBool &result, mtpRequestId req); void sendActionDone(const MTPBool &result, mtpRequestId req);
void destroyData(); void destroyData();
void uploadImage(const QImage &img, bool withText = false, const QString &source = QString()); void uploadImage(const QImage &img, bool withText = false, const QString &source = QString());
@ -489,6 +491,8 @@ public slots:
void onReplyToMessage(); void onReplyToMessage();
void onReplyForwardPreviewCancel(); void onReplyForwardPreviewCancel();
void onCancelSendAction();
void onStickerPackInfo(); void onStickerPackInfo();
void onPreviewParse(); void onPreviewParse();
@ -498,16 +502,16 @@ public slots:
void peerUpdated(PeerData *data); void peerUpdated(PeerData *data);
void onFullPeerUpdated(PeerData *data); void onFullPeerUpdated(PeerData *data);
void cancelTyping();
void onPhotoUploaded(MsgId msgId, const MTPInputFile &file); void onPhotoUploaded(MsgId msgId, const MTPInputFile &file);
void onDocumentUploaded(MsgId msgId, const MTPInputFile &file); void onDocumentUploaded(MsgId msgId, const MTPInputFile &file);
void onThumbDocumentUploaded(MsgId msgId, const MTPInputFile &file, const MTPInputFile &thumb); void onThumbDocumentUploaded(MsgId msgId, const MTPInputFile &file, const MTPInputFile &thumb);
void onAudioUploaded(MsgId msgId, const MTPInputFile &file); void onAudioUploaded(MsgId msgId, const MTPInputFile &file);
void onPhotoProgress(MsgId msgId);
void onDocumentProgress(MsgId msgId); void onDocumentProgress(MsgId msgId);
void onAudioProgress(MsgId msgId); void onAudioProgress(MsgId msgId);
void onPhotoFailed(MsgId msgId);
void onDocumentFailed(MsgId msgId); void onDocumentFailed(MsgId msgId);
void onAudioFailed(MsgId msgId); void onAudioFailed(MsgId msgId);
@ -685,8 +689,8 @@ private:
QTimer _animActiveTimer; QTimer _animActiveTimer;
float64 _animActiveStart; float64 _animActiveStart;
mtpRequestId _typingRequest; QMap<QPair<History*, SendActionType>, mtpRequestId> _sendActionRequests;
QTimer _typingStopTimer; QTimer _sendActionStopTimer;
uint64 _saveDraftStart; uint64 _saveDraftStart;
bool _saveDraftText; bool _saveDraftText;

View File

@ -3483,11 +3483,7 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
History *history = App::historyLoaded(App::peerFromUser(d.vuser_id)); History *history = App::historyLoaded(App::peerFromUser(d.vuser_id));
UserData *user = App::userLoaded(d.vuser_id.v); UserData *user = App::userLoaded(d.vuser_id.v);
if (history && user) { if (history && user) {
if (d.vaction.type() == mtpc_sendMessageTypingAction) { App::histories().regSendAction(history, user, d.vaction);
App::histories().regTyping(history, user);
} else if (d.vaction.type() == mtpc_sendMessageCancelAction) {
history->unregTyping(user);
}
} }
} break; } break;
@ -3496,7 +3492,7 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
History *history = App::historyLoaded(App::peerFromChat(d.vchat_id)); History *history = App::historyLoaded(App::peerFromChat(d.vchat_id));
UserData *user = (d.vuser_id.v == MTP::authedId()) ? 0 : App::userLoaded(d.vuser_id.v); UserData *user = (d.vuser_id.v == MTP::authedId()) ? 0 : App::userLoaded(d.vuser_id.v);
if (history && user) { if (history && user) {
App::histories().regTyping(history, user); App::histories().regSendAction(history, user, d.vaction);
} }
} break; } break;

View File

@ -11,7 +11,7 @@
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>APPL</string> <string>APPL</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>0.8.43</string> <string>0.8.44</string>
<key>LSMinimumSystemVersion</key> <key>LSMinimumSystemVersion</key>
<string>$(MACOSX_DEPLOYMENT_TARGET)</string> <string>$(MACOSX_DEPLOYMENT_TARGET)</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>

Binary file not shown.

View File

@ -1707,7 +1707,7 @@
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
COPY_PHASE_STRIP = NO; COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 0.8.43; CURRENT_PROJECT_VERSION = 0.8.44;
DEBUG_INFORMATION_FORMAT = dwarf; DEBUG_INFORMATION_FORMAT = dwarf;
GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
GCC_OPTIMIZATION_LEVEL = 0; GCC_OPTIMIZATION_LEVEL = 0;
@ -1725,7 +1725,7 @@
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
COPY_PHASE_STRIP = YES; COPY_PHASE_STRIP = YES;
CURRENT_PROJECT_VERSION = 0.8.43; CURRENT_PROJECT_VERSION = 0.8.44;
GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
GCC_OPTIMIZATION_LEVEL = fast; GCC_OPTIMIZATION_LEVEL = fast;
GCC_PREFIX_HEADER = ./SourceFiles/stdafx.h; GCC_PREFIX_HEADER = ./SourceFiles/stdafx.h;
@ -1751,10 +1751,10 @@
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = ""; CODE_SIGN_IDENTITY = "";
COPY_PHASE_STRIP = NO; COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 0.8.43; CURRENT_PROJECT_VERSION = 0.8.44;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DYLIB_COMPATIBILITY_VERSION = 0.8; DYLIB_COMPATIBILITY_VERSION = 0.8;
DYLIB_CURRENT_VERSION = 0.8.43; DYLIB_CURRENT_VERSION = 0.8.44;
ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_STRICT_OBJC_MSGSEND = YES;
FRAMEWORK_SEARCH_PATHS = ""; FRAMEWORK_SEARCH_PATHS = "";
GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
@ -1885,10 +1885,10 @@
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = ""; CODE_SIGN_IDENTITY = "";
COPY_PHASE_STRIP = NO; COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 0.8.43; CURRENT_PROJECT_VERSION = 0.8.44;
DEBUG_INFORMATION_FORMAT = dwarf; DEBUG_INFORMATION_FORMAT = dwarf;
DYLIB_COMPATIBILITY_VERSION = 0.8; DYLIB_COMPATIBILITY_VERSION = 0.8;
DYLIB_CURRENT_VERSION = 0.8.43; DYLIB_CURRENT_VERSION = 0.8.44;
ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_STRICT_OBJC_MSGSEND = YES;
FRAMEWORK_SEARCH_PATHS = ""; FRAMEWORK_SEARCH_PATHS = "";
GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES;

View File

@ -1,2 +1,2 @@
echo 0.8 8043 0.8.43 0 echo 0.8 8044 0.8.44 1
# AppVersionStrMajor AppVersion AppVersionStr DevChannel # AppVersionStrMajor AppVersion AppVersionStr DevChannel