version 0.8.30 with bots support and forward-by-dragndrop

This commit is contained in:
John Preston 2015-06-24 20:24:48 +03:00
parent 780d00bd8c
commit 793a2ec90c
26 changed files with 396 additions and 111 deletions

View File

@ -1,10 +1,10 @@
@echo OFF @echo OFF
set "AppVersion=8029" set "AppVersion=8030"
set "AppVersionStrSmall=0.8.29" set "AppVersionStrSmall=0.8.30"
set "AppVersionStr=0.8.29" set "AppVersionStr=0.8.30"
set "AppVersionStrFull=0.8.29.0" set "AppVersionStrFull=0.8.30.0"
set "DevChannel=1" set "DevChannel=0"
if %DevChannel% neq 0 goto preparedev if %DevChannel% neq 0 goto preparedev

View File

@ -993,15 +993,21 @@ btnAttachEmoji: iconedButton(btnAttachDocument) {
width: 33px; width: 33px;
} }
btnBotKbShow: iconedButton(btnAttachEmoji) { btnBotKbShow: iconedButton(btnAttachEmoji) {
icon: sprite(375px, 74px, 21px, 16px); icon: sprite(375px, 74px, 21px, 21px);
iconPos: point(6px, 16px); iconPos: point(6px, 12px);
downIcon: sprite(375px, 74px, 21px, 16px); downIcon: sprite(375px, 74px, 21px, 21px);
downIconPos: point(6px, 16px); downIconPos: point(6px, 12px);
}
btnBotCmdStart: iconedButton(btnAttachEmoji) {
icon: sprite(354px, 74px, 21px, 21px);
iconPos: point(6px, 12px);
downIcon: sprite(354px, 74px, 21px, 21px);
downIconPos: point(6px, 12px);
} }
btnBotKbHide: iconedButton(btnAttachEmoji) { btnBotKbHide: iconedButton(btnAttachEmoji) {
icon: sprite(352px, 74px, 23px, 14px); icon: sprite(373px, 95px, 23px, 14px);
iconPos: point(5px, 17px); iconPos: point(5px, 17px);
downIcon: sprite(352px, 74px, 23px, 14px); downIcon: sprite(373px, 95px, 23px, 14px);
downIconPos: point(5px, 17px); downIconPos: point(5px, 17px);
} }
btnRecordAudio: sprite(363px, 366px, 16px, 24px); btnRecordAudio: sprite(363px, 366px, 16px, 24px);

View File

@ -312,7 +312,11 @@ namespace App {
return lng_status_lastseen_date(lt_date, dOnline.date().toString(qsl("dd.MM.yy"))); return lng_status_lastseen_date(lt_date, dOnline.date().toString(qsl("dd.MM.yy")));
} }
bool onlineColorUse(int32 online, int32 now) { bool onlineColorUse(UserData *user, int32 now) {
if (isServiceUser(user->id) || user->botInfo) {
return false;
}
int32 online = user->onlineTill;
if (online <= 0) { if (online <= 0) {
switch (online) { switch (online) {
case 0: case 0:

View File

@ -105,7 +105,7 @@ namespace App {
int32 onlineForSort(UserData *user, int32 now); int32 onlineForSort(UserData *user, int32 now);
int32 onlineWillChangeIn(UserData *user, int32 nowOnServer); int32 onlineWillChangeIn(UserData *user, int32 nowOnServer);
QString onlineText(UserData *user, int32 nowOnServer, bool precise = false); QString onlineText(UserData *user, int32 nowOnServer, bool precise = false);
bool onlineColorUse(int32 online, int32 now); bool onlineColorUse(UserData *user, int32 now);
UserData *feedUsers(const MTPVector<MTPUser> &users); // returns last user UserData *feedUsers(const MTPVector<MTPUser> &users); // returns last user
ChatData *feedChats(const MTPVector<MTPChat> &chats); // returns last chat ChatData *feedChats(const MTPVector<MTPChat> &chats); // returns last chat

View File

@ -642,7 +642,7 @@ void Application::checkMapVersion() {
QString versionFeatures; QString versionFeatures;
if (DevChannel && Local::oldMapVersion() < 8029) { if (DevChannel && Local::oldMapVersion() < 8029) {
versionFeatures = lang(lng_new_version_minor);// QString::fromUtf8("\xe2\x80\x94 IPv6 connections support\n\xe2\x80\x94 Bug fixes and minor stuff");// .replace('@', qsl("@") + QChar(0x200D)); versionFeatures = lang(lng_new_version_minor);// QString::fromUtf8("\xe2\x80\x94 IPv6 connections support\n\xe2\x80\x94 Bug fixes and minor stuff");// .replace('@', qsl("@") + QChar(0x200D));
} else if (!DevChannel && Local::oldMapVersion() < 8024) { } else if (!DevChannel && Local::oldMapVersion() < 8030) {
versionFeatures = lng_new_version_text(lt_blog_link, qsl("https://telegram.org/blog/bot-revolution"));// lang(lng_new_version_text).trimmed(); versionFeatures = lng_new_version_text(lt_blog_link, qsl("https://telegram.org/blog/bot-revolution"));// lang(lng_new_version_text).trimmed();
} }
if (!versionFeatures.isEmpty()) { if (!versionFeatures.isEmpty()) {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 167 KiB

After

Width:  |  Height:  |  Size: 167 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 219 KiB

After

Width:  |  Height:  |  Size: 220 KiB

View File

@ -249,7 +249,7 @@ void ContactsInner::paintDialog(QPainter &p, PeerData *peer, ContactData *data,
} else { } else {
if (data->inchat || data->check) { if (data->inchat || data->check) {
p.setPen(st::white->p); p.setPen(st::white->p);
} else if (user && (uname || App::onlineColorUse(user->onlineTill, _time))) { } else if (user && (uname || App::onlineColorUse(user, _time))) {
p.setPen(st::profileOnlineColor->p); p.setPen(st::profileOnlineColor->p);
} else { } else {
p.setPen(st::profileOfflineColor->p); p.setPen(st::profileOfflineColor->p);

View File

@ -235,7 +235,6 @@ void StickerSetBox::onAddStickers() {
void StickerSetBox::onShareStickers() { void StickerSetBox::onShareStickers() {
QString url = qsl("https://telegram.me/addstickers/") + _inner.shortName(); QString url = qsl("https://telegram.me/addstickers/") + _inner.shortName();
DEBUG_LOG(("Setting text to clipboard from stickerset box: %1").arg(url));
QApplication::clipboard()->setText(url); QApplication::clipboard()->setText(url);
App::wnd()->showLayer(new ConfirmBox(lang(lng_stickers_copied), true), true); App::wnd()->showLayer(new ConfirmBox(lang(lng_stickers_copied), true), true);
} }

View File

@ -17,9 +17,9 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
*/ */
#pragma once #pragma once
static const int32 AppVersion = 8029; static const int32 AppVersion = 8030;
static const wchar_t *AppVersionStr = L"0.8.29"; static const wchar_t *AppVersionStr = L"0.8.30";
static const bool DevChannel = true; static const bool DevChannel = false;
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

@ -680,6 +680,26 @@ void DialogsListWidget::itemReplaced(HistoryItem *oldItem, HistoryItem *newItem)
} }
} }
PeerData *DialogsListWidget::updateFromParentDrag(QPoint globalPos) {
lastMousePos = globalPos;
selByMouse = true;
onUpdateSelected(true);
update();
if (_state == DefaultState) {
if (sel) return sel->history->peer;
} else if (_state == FilteredState || _state == SearchedState) {
if (filteredSel >= 0 && filteredSel < filterResults.size()) {
return filterResults[filteredSel]->history->peer;
} else if (peopleSel >= 0 && peopleSel < peopleResults.size()) {
return peopleResults[peopleSel];
} else if (searchedSel >= 0 && searchedSel < searchResults.size()) {
return searchResults[searchedSel]->_item->history()->peer;
}
}
return 0;
}
void DialogsListWidget::itemRemoved(HistoryItem *item) { void DialogsListWidget::itemRemoved(HistoryItem *item) {
int wasCount = searchResults.size(); int wasCount = searchResults.size();
for (int i = 0; i < searchResults.size();) { for (int i = 0; i < searchResults.size();) {
@ -1356,6 +1376,8 @@ MsgId DialogsListWidget::lastSearchId() const {
DialogsWidget::DialogsWidget(MainWidget *parent) : QWidget(parent) DialogsWidget::DialogsWidget(MainWidget *parent) : QWidget(parent)
, _drawShadow(true) , _drawShadow(true)
, _dragInScroll(false)
, _dragForward(false)
, dlgOffset(0) , dlgOffset(0)
, dlgCount(-1) , dlgCount(-1)
, dlgPreloading(0) , dlgPreloading(0)
@ -1388,6 +1410,8 @@ DialogsWidget::DialogsWidget(MainWidget *parent) : QWidget(parent)
connect(&_newGroup, SIGNAL(clicked()), this, SLOT(onNewGroup())); connect(&_newGroup, SIGNAL(clicked()), this, SLOT(onNewGroup()));
connect(&_cancelSearch, SIGNAL(clicked()), this, SLOT(onCancelSearch())); connect(&_cancelSearch, SIGNAL(clicked()), this, SLOT(onCancelSearch()));
setAcceptDrops(true);
_searchTimer.setSingleShot(true); _searchTimer.setSingleShot(true);
connect(&_searchTimer, SIGNAL(timeout()), this, SLOT(onSearchMessages())); connect(&_searchTimer, SIGNAL(timeout()), this, SLOT(onSearchMessages()));
@ -1741,6 +1765,69 @@ bool DialogsWidget::addNewContact(int32 uid, bool show) {
return true; return true;
} }
void DialogsWidget::dragEnterEvent(QDragEnterEvent *e) {
if (App::main()->selectingPeer()) return;
_dragInScroll = false;
_dragForward = cWideMode() && e->mimeData()->hasFormat(qsl("application/x-td-forward-selected"));
if (_dragForward) {
e->setDropAction(Qt::CopyAction);
e->accept();
updateDragInScroll(scroll.geometry().contains(e->pos()));
} else if (false && App::main() && App::main()->getDragState(e->mimeData()) != DragStateNone) {
e->setDropAction(Qt::CopyAction);
e->accept();
}
}
void DialogsWidget::dragMoveEvent(QDragMoveEvent *e) {
if (scroll.geometry().contains(e->pos())) {
if (_dragForward) updateDragInScroll(true);
PeerData *p = list.updateFromParentDrag(mapToGlobal(e->pos()));
if (p) {
e->setDropAction(Qt::CopyAction);
} else {
e->setDropAction(Qt::IgnoreAction);
}
} else {
if (_dragForward) updateDragInScroll(false);
list.leaveEvent(0);
e->setDropAction(Qt::IgnoreAction);
}
e->accept();
}
void DialogsWidget::dragLeaveEvent(QDragLeaveEvent *e) {
if (_dragForward) updateDragInScroll(false);
list.leaveEvent(0);
e->accept();
}
void DialogsWidget::updateDragInScroll(bool inScroll) {
if (_dragInScroll != inScroll) {
_dragInScroll = inScroll;
if (_dragInScroll) {
App::main()->forwardLayer(1);
} else {
App::main()->dialogsCancelled();
}
}
}
void DialogsWidget::dropEvent(QDropEvent *e) {
if (scroll.geometry().contains(e->pos())) {
PeerData *p = list.updateFromParentDrag(mapToGlobal(e->pos()));
if (p) {
e->acceptProposedAction();
if (e->mimeData()->hasFormat(qsl("application/x-td-forward-selected"))) {
App::main()->onForward(p->id, true);
} else {
App::main()->showPeer(p->id, 0, false, true);
}
}
}
}
void DialogsWidget::onListScroll() { void DialogsWidget::onListScroll() {
// if (!App::self()) return; // if (!App::self()) return;

View File

@ -98,6 +98,8 @@ public:
void itemRemoved(HistoryItem *item); void itemRemoved(HistoryItem *item);
void itemReplaced(HistoryItem *oldItem, HistoryItem *newItem); void itemReplaced(HistoryItem *oldItem, HistoryItem *newItem);
PeerData *updateFromParentDrag(QPoint globalPos);
~DialogsListWidget(); ~DialogsListWidget();
public slots: public slots:
@ -171,6 +173,12 @@ public:
void peopleReceived(const MTPcontacts_Found &result, mtpRequestId req); void peopleReceived(const MTPcontacts_Found &result, mtpRequestId req);
bool addNewContact(int32 uid, bool show = true); bool addNewContact(int32 uid, bool show = true);
void dragEnterEvent(QDragEnterEvent *e);
void dragMoveEvent(QDragMoveEvent *e);
void dragLeaveEvent(QDragLeaveEvent *e);
void dropEvent(QDropEvent *e);
void updateDragInScroll(bool inScroll);
void resizeEvent(QResizeEvent *e); void resizeEvent(QResizeEvent *e);
void keyPressEvent(QKeyEvent *e); void keyPressEvent(QKeyEvent *e);
void paintEvent(QPaintEvent *e); void paintEvent(QPaintEvent *e);
@ -232,6 +240,8 @@ private:
bool _drawShadow; bool _drawShadow;
bool _dragInScroll, _dragForward;
void unreadCountsReceived(const QVector<MTPDialog> &dialogs); void unreadCountsReceived(const QVector<MTPDialog> &dialogs);
bool dialogsFailed(const RPCError &error); bool dialogsFailed(const RPCError &error);
bool contactsFailed(const RPCError &error); bool contactsFailed(const RPCError &error);

View File

@ -2425,7 +2425,8 @@ void MentionsInner::paintEvent(QPaintEvent *e) {
QPainter p(this); QPainter p(this);
int32 atwidth = st::mentionFont->m.width('@'), hashwidth = st::mentionFont->m.width('#'); int32 atwidth = st::mentionFont->m.width('@'), hashwidth = st::mentionFont->m.width('#');
int32 availwidth = width() - 2 * st::mentionPadding.left() - st::mentionPhotoSize - 2 * st::mentionPadding.right(); int32 mentionleft = 2 * st::mentionPadding.left() + st::mentionPhotoSize;
int32 mentionwidth = width() - mentionleft - 2 * st::mentionPadding.right();
int32 htagleft = st::btnAttachPhoto.width + st::taMsgField.textMrg.left() - st::dlgShadow, htagwidth = width() - st::mentionPadding.right() - htagleft - st::mentionScroll.width; int32 htagleft = st::btnAttachPhoto.width + st::taMsgField.textMrg.left() - st::dlgShadow, htagwidth = width() - st::mentionPadding.right() - htagleft - st::mentionScroll.width;
int32 from = qFloor(e->rect().top() / st::mentionHeight), to = qFloor(e->rect().bottom() / st::mentionHeight) + 1; int32 from = qFloor(e->rect().top() / st::mentionHeight), to = qFloor(e->rect().bottom() / st::mentionHeight) + 1;
@ -2445,9 +2446,9 @@ void MentionsInner::paintEvent(QPaintEvent *e) {
UserData *user = _rows->at(i); UserData *user = _rows->at(i);
QString first = (_parent->filter().size() < 2) ? QString() : ('@' + user->username.mid(0, _parent->filter().size() - 1)), second = (_parent->filter().size() < 2) ? ('@' + user->username) : user->username.mid(_parent->filter().size() - 1); QString first = (_parent->filter().size() < 2) ? QString() : ('@' + user->username.mid(0, _parent->filter().size() - 1)), second = (_parent->filter().size() < 2) ? ('@' + user->username) : user->username.mid(_parent->filter().size() - 1);
int32 firstwidth = st::mentionFont->m.width(first), secondwidth = st::mentionFont->m.width(second), unamewidth = firstwidth + secondwidth, namewidth = user->nameText.maxWidth(); int32 firstwidth = st::mentionFont->m.width(first), secondwidth = st::mentionFont->m.width(second), unamewidth = firstwidth + secondwidth, namewidth = user->nameText.maxWidth();
if (availwidth < unamewidth + namewidth) { if (mentionwidth < unamewidth + namewidth) {
namewidth = (availwidth * namewidth) / (namewidth + unamewidth); namewidth = (mentionwidth * namewidth) / (namewidth + unamewidth);
unamewidth = availwidth - namewidth; unamewidth = mentionwidth - namewidth;
if (firstwidth < unamewidth + st::mentionFont->elidew) { if (firstwidth < unamewidth + st::mentionFont->elidew) {
if (firstwidth < unamewidth) { if (firstwidth < unamewidth) {
first = st::mentionFont->m.elidedText(first, Qt::ElideRight, unamewidth); first = st::mentionFont->m.elidedText(first, Qt::ElideRight, unamewidth);
@ -2465,10 +2466,10 @@ void MentionsInner::paintEvent(QPaintEvent *e) {
p.setFont(st::mentionFont->f); p.setFont(st::mentionFont->f);
p.setPen((selected ? st::mentionFgOverActive : st::mentionFgActive)->p); p.setPen((selected ? st::mentionFgOverActive : st::mentionFgActive)->p);
p.drawText(2 * st::mentionPadding.left() + st::mentionPhotoSize + namewidth + st::mentionPadding.right(), i * st::mentionHeight + st::mentionTop + st::mentionFont->ascent, first); p.drawText(mentionleft + namewidth + st::mentionPadding.right(), i * st::mentionHeight + st::mentionTop + st::mentionFont->ascent, first);
if (!second.isEmpty()) { if (!second.isEmpty()) {
p.setPen((selected ? st::mentionFgOver : st::mentionFg)->p); p.setPen((selected ? st::mentionFgOver : st::mentionFg)->p);
p.drawText(2 * st::mentionPadding.left() + st::mentionPhotoSize + namewidth + st::mentionPadding.right() + firstwidth, i * st::mentionHeight + st::mentionTop + st::mentionFont->ascent, second); p.drawText(mentionleft + namewidth + st::mentionPadding.right() + firstwidth, i * st::mentionHeight + st::mentionTop + st::mentionFont->ascent, second);
} }
} else if (!_hrows->isEmpty()) { } else if (!_hrows->isEmpty()) {
QString hrow = _hrows->at(i); QString hrow = _hrows->at(i);
@ -2501,30 +2502,30 @@ void MentionsInner::paintEvent(QPaintEvent *e) {
if (hasUsername || botStatus == 0 || botStatus == 2) { if (hasUsername || botStatus == 0 || botStatus == 2) {
toHighlight += '@' + user->username; toHighlight += '@' + user->username;
} }
if (_parent->chat() || botStatus == 0 || botStatus == 2) { if (true || _parent->chat() || botStatus == 0 || botStatus == 2) {
user->photo->load(); user->photo->load();
p.drawPixmap(st::mentionPadding.left(), i * st::mentionHeight + st::mentionPadding.top(), user->photo->pixRounded(st::mentionPhotoSize)); p.drawPixmap(st::mentionPadding.left(), i * st::mentionHeight + st::mentionPadding.top(), user->photo->pixRounded(st::mentionPhotoSize));
} }
int32 addleft = 0, widthleft = htagwidth; int32 addleft = 0, widthleft = mentionwidth;
QString first = (_parent->filter().size() < 2) ? QString() : ('/' + toHighlight.mid(0, _parent->filter().size() - 1)), second = (_parent->filter().size() < 2) ? ('/' + toHighlight) : toHighlight.mid(_parent->filter().size() - 1); QString first = (_parent->filter().size() < 2) ? QString() : ('/' + toHighlight.mid(0, _parent->filter().size() - 1)), second = (_parent->filter().size() < 2) ? ('/' + toHighlight) : toHighlight.mid(_parent->filter().size() - 1);
int32 firstwidth = st::mentionFont->m.width(first), secondwidth = st::mentionFont->m.width(second); int32 firstwidth = st::mentionFont->m.width(first), secondwidth = st::mentionFont->m.width(second);
if (htagwidth < firstwidth + secondwidth) { if (widthleft < firstwidth + secondwidth) {
if (htagwidth < firstwidth + st::mentionFont->elidew) { if (widthleft < firstwidth + st::mentionFont->elidew) {
first = st::mentionFont->m.elidedText(first + second, Qt::ElideRight, htagwidth); first = st::mentionFont->m.elidedText(first + second, Qt::ElideRight, widthleft);
second = QString(); second = QString();
} else { } else {
second = st::mentionFont->m.elidedText(second, Qt::ElideRight, htagwidth - firstwidth); second = st::mentionFont->m.elidedText(second, Qt::ElideRight, widthleft - firstwidth);
} }
} }
p.setFont(st::mentionFont->f); p.setFont(st::mentionFont->f);
if (!first.isEmpty()) { if (!first.isEmpty()) {
p.setPen((selected ? st::mentionFgOverActive : st::mentionFgActive)->p); p.setPen((selected ? st::mentionFgOverActive : st::mentionFgActive)->p);
p.drawText(htagleft, i * st::mentionHeight + st::mentionTop + st::mentionFont->ascent, first); p.drawText(mentionleft, i * st::mentionHeight + st::mentionTop + st::mentionFont->ascent, first);
} }
if (!second.isEmpty()) { if (!second.isEmpty()) {
p.setPen((selected ? st::mentionFgOver : st::mentionFg)->p); p.setPen((selected ? st::mentionFgOver : st::mentionFg)->p);
p.drawText(htagleft + firstwidth, i * st::mentionHeight + st::mentionTop + st::mentionFont->ascent, second); p.drawText(mentionleft + firstwidth, i * st::mentionHeight + st::mentionTop + st::mentionFont->ascent, second);
} }
addleft += firstwidth + secondwidth + st::mentionPadding.left(); addleft += firstwidth + secondwidth + st::mentionPadding.left();
widthleft -= firstwidth + secondwidth + st::mentionPadding.left(); widthleft -= firstwidth + secondwidth + st::mentionPadding.left();
@ -2538,7 +2539,7 @@ void MentionsInner::paintEvent(QPaintEvent *e) {
descwidth = st::mentionFont->m.width(description); descwidth = st::mentionFont->m.width(description);
} }
p.setPen((selected ? st::mentionFgOver : st::mentionFg)->p); p.setPen((selected ? st::mentionFgOver : st::mentionFg)->p);
p.drawText(htagleft + addleft + (widthleft - descwidth), i * st::mentionHeight + st::mentionTop + st::mentionFont->ascent, description); p.drawText(mentionleft + addleft + (widthleft - descwidth), i * st::mentionHeight + st::mentionTop + st::mentionFont->ascent, description);
} }
} }
} }

View File

@ -289,7 +289,7 @@ public:
QString encoded() const { QString encoded() const {
QUrl u(_url), good(u.isValid() ? u.toEncoded() : QString()); QUrl u(_url), good(u.isValid() ? u.toEncoded() : QString());
QString result(good.isValid() ? good.toEncoded() : _url); QString result(good.isValid() ? QString::fromUtf8(good.toEncoded()) : _url);
if (!QRegularExpression(qsl("^[a-zA-Z]+://")).match(result).hasMatch()) { // no protocol if (!QRegularExpression(qsl("^[a-zA-Z]+://")).match(result).hasMatch()) { // no protocol
return qsl("http://") + result; return qsl("http://") + result;

View File

@ -326,6 +326,12 @@ History::History(const PeerId &peerId) : width(0), height(0)
} }
} }
void History::clearLastKeyboard() {
lastKeyboardInited = true;
lastKeyboardId = 0;
lastKeyboardFrom = 0;
}
void History::updateNameText() { void History::updateNameText() {
nameText.setText(st::msgNameFont, peer->nameOrPhone.isEmpty() ? peer->name : peer->nameOrPhone, _textNameOptions); nameText.setText(st::msgNameFont, peer->nameOrPhone.isEmpty() ? peer->name : peer->nameOrPhone, _textNameOptions);
} }
@ -632,9 +638,7 @@ HistoryItem *History::createItem(HistoryBlock *block, const MTPmessage &msg, boo
case mtpc_messageActionChatDeleteUser: { case mtpc_messageActionChatDeleteUser: {
const MTPDmessageActionChatDeleteUser &d(action.c_messageActionChatDeleteUser()); const MTPDmessageActionChatDeleteUser &d(action.c_messageActionChatDeleteUser());
if (lastKeyboardFrom == App::peerFromUser(d.vuser_id)) { if (lastKeyboardFrom == App::peerFromUser(d.vuser_id)) {
lastKeyboardInited = true; clearLastKeyboard();
lastKeyboardId = 0;
lastKeyboardFrom = 0;
} }
// App::peer(App::peerFromUser(d.vuser_id)); left // App::peer(App::peerFromUser(d.vuser_id)); left
} break; } break;
@ -828,14 +832,10 @@ HistoryItem *History::doAddToBack(HistoryBlock *to, bool newBlock, HistoryItem *
} }
if (markupFlags & MTPDreplyKeyboardMarkup_flag_ZERO) { // zero markup means replyKeyboardHide if (markupFlags & MTPDreplyKeyboardMarkup_flag_ZERO) { // zero markup means replyKeyboardHide
if (lastKeyboardFrom == adding->from()->id || (!lastKeyboardInited && !peer->chat && !adding->out())) { if (lastKeyboardFrom == adding->from()->id || (!lastKeyboardInited && !peer->chat && !adding->out())) {
lastKeyboardInited = true; clearLastKeyboard();
lastKeyboardId = 0;
lastKeyboardFrom = 0;
} }
} else if (peer->chat && (peer->asChat()->count < 1 || !peer->asChat()->participants.isEmpty()) && !peer->asChat()->participants.contains(adding->from())) { } else if (peer->chat && (peer->asChat()->count < 1 || !peer->asChat()->participants.isEmpty()) && !peer->asChat()->participants.contains(adding->from())) {
lastKeyboardInited = true; clearLastKeyboard();
lastKeyboardId = 0;
lastKeyboardFrom = 0;
} else { } else {
lastKeyboardInited = true; lastKeyboardInited = true;
lastKeyboardId = adding->id; lastKeyboardId = adding->id;
@ -960,11 +960,10 @@ void History::addToFront(const QVector<MTPMessage> &slice) {
} }
if (!(markupFlags & MTPDreplyKeyboardMarkup_flag_ZERO)) { if (!(markupFlags & MTPDreplyKeyboardMarkup_flag_ZERO)) {
if (!lastKeyboardInited) { if (!lastKeyboardInited) {
lastKeyboardInited = true;
if (wasKeyboardHide || ((peer->asChat()->count < 1 || !peer->asChat()->participants.isEmpty()) && !peer->asChat()->participants.contains(item->from()))) { if (wasKeyboardHide || ((peer->asChat()->count < 1 || !peer->asChat()->participants.isEmpty()) && !peer->asChat()->participants.contains(item->from()))) {
lastKeyboardId = 0; clearLastKeyboard();
lastKeyboardFrom = 0;
} else { } else {
lastKeyboardInited = true;
lastKeyboardId = item->id; lastKeyboardId = item->id;
lastKeyboardFrom = item->from()->id; lastKeyboardFrom = item->from()->id;
lastKeyboardUsed = false; lastKeyboardUsed = false;
@ -976,10 +975,8 @@ void History::addToFront(const QVector<MTPMessage> &slice) {
} else if (!lastKeyboardInited && item->hasReplyMarkup() && !item->out()) { // conversations with bots } else if (!lastKeyboardInited && item->hasReplyMarkup() && !item->out()) { // conversations with bots
int32 markupFlags = App::replyMarkup(item->id).flags; int32 markupFlags = App::replyMarkup(item->id).flags;
if (!(markupFlags & MTPDreplyKeyboardMarkup_flag_personal) || item->notifyByFrom()) { if (!(markupFlags & MTPDreplyKeyboardMarkup_flag_personal) || item->notifyByFrom()) {
lastKeyboardInited = true;
if (markupFlags & MTPDreplyKeyboardMarkup_flag_ZERO) { if (markupFlags & MTPDreplyKeyboardMarkup_flag_ZERO) {
lastKeyboardId = 0; clearLastKeyboard();
lastKeyboardFrom = 0;
} else { } else {
lastKeyboardInited = true; lastKeyboardInited = true;
lastKeyboardId = item->id; lastKeyboardId = item->id;

View File

@ -254,6 +254,7 @@ struct History : public QList<HistoryBlock*> {
bool lastKeyboardInited, lastKeyboardUsed; bool lastKeyboardInited, lastKeyboardUsed;
MsgId lastKeyboardId; MsgId lastKeyboardId;
PeerId lastKeyboardFrom; PeerId lastKeyboardFrom;
void clearLastKeyboard();
mtpRequestId sendRequestId; mtpRequestId sendRequestId;

View File

@ -51,6 +51,7 @@ HistoryList::HistoryList(HistoryWidget *historyWidget, ScrollArea *scroll, Histo
, _dragSelFrom(0) , _dragSelFrom(0)
, _dragSelTo(0) , _dragSelTo(0)
, _dragSelecting(false) , _dragSelecting(false)
, _wasSelectedText(false)
, _touchScroll(false) , _touchScroll(false)
, _touchSelect(false) , _touchSelect(false)
, _touchInProgress(false) , _touchInProgress(false)
@ -482,6 +483,7 @@ void HistoryList::dragActionCancel() {
_dragAction = NoDrag; _dragAction = NoDrag;
_dragStartPos = QPoint(0, 0); _dragStartPos = QPoint(0, 0);
_dragSelFrom = _dragSelTo = 0; _dragSelFrom = _dragSelTo = 0;
_wasSelectedText = false;
historyWidget->noSelectingScroll(); historyWidget->noSelectingScroll();
} }
@ -542,6 +544,9 @@ void HistoryList::dragActionFinish(const QPoint &screenPos, Qt::MouseButton butt
updateMsg(App::pressedItem()); updateMsg(App::pressedItem());
App::pressedItem(0); App::pressedItem(0);
} }
_wasSelectedText = false;
if (needClick) { if (needClick) {
DEBUG_LOG(("Clicked link: %1 (%2) %3").arg(needClick->text()).arg(needClick->readable()).arg(needClick->encoded())); DEBUG_LOG(("Clicked link: %1 (%2) %3").arg(needClick->text()).arg(needClick->readable()).arg(needClick->encoded()));
needClick->onClick(button); needClick->onClick(button);
@ -573,6 +578,7 @@ void HistoryList::dragActionFinish(const QPoint &screenPos, Qt::MouseButton butt
} else if (_dragAction == Selecting) { } else if (_dragAction == Selecting) {
if (_dragSelFrom && _dragSelTo) { if (_dragSelFrom && _dragSelTo) {
applyDragSelection(); applyDragSelection();
_dragSelFrom = _dragSelTo = 0;
} else if (!_selected.isEmpty() && !_dragWasInactive) { } else if (!_selected.isEmpty() && !_dragWasInactive) {
uint32 sel = _selected.cbegin().value(); uint32 sel = _selected.cbegin().value();
if (sel != FullItemSel && (sel & 0xFFFF) == ((sel >> 16) & 0xFFFF)) { if (sel != FullItemSel && (sel & 0xFFFF) == ((sel >> 16) & 0xFFFF)) {
@ -595,6 +601,8 @@ void HistoryList::mouseReleaseEvent(QMouseEvent *e) {
} }
void HistoryList::mouseDoubleClickEvent(QMouseEvent *e) { void HistoryList::mouseDoubleClickEvent(QMouseEvent *e) {
if (!hist) return;
if (((_dragAction == Selecting && !_selected.isEmpty() && _selected.cbegin().value() != FullItemSel) || (_dragAction == NoDrag && (_selected.isEmpty() || _selected.cbegin().value() != FullItemSel))) && _dragSelType == TextSelectLetters && _dragItem) { if (((_dragAction == Selecting && !_selected.isEmpty() && _selected.cbegin().value() != FullItemSel) || (_dragAction == NoDrag && (_selected.isEmpty() || _selected.cbegin().value() != FullItemSel))) && _dragSelType == TextSelectLetters && _dragItem) {
bool afterDragSymbol, uponSelected; bool afterDragSymbol, uponSelected;
uint16 symbol; uint16 symbol;
@ -610,7 +618,7 @@ void HistoryList::mouseDoubleClickEvent(QMouseEvent *e) {
_selected.clear(); _selected.clear();
} }
_selected.insert(_dragItem, selStatus); _selected.insert(_dragItem, selStatus);
} }
mouseMoveEvent(e); mouseMoveEvent(e);
_trippleClickPoint = e->globalPos(); _trippleClickPoint = e->globalPos();
@ -800,8 +808,9 @@ void HistoryList::onMenuDestroy(QObject *obj) {
void HistoryList::copySelectedText() { void HistoryList::copySelectedText() {
QString sel = getSelectedText(); QString sel = getSelectedText();
DEBUG_LOG(("Setting selected text to clipboard: %1").arg(sel)); if (!sel.isEmpty()) {
QApplication::clipboard()->setText(sel); QApplication::clipboard()->setText(sel);
}
} }
void HistoryList::openContextUrl() { void HistoryList::openContextUrl() {
@ -814,7 +823,6 @@ void HistoryList::openContextUrl() {
void HistoryList::copyContextUrl() { void HistoryList::copyContextUrl() {
QString enc = _contextMenuLnk->encoded(); QString enc = _contextMenuLnk->encoded();
if (!enc.isEmpty()) { if (!enc.isEmpty()) {
DEBUG_LOG(("Setting text to clipboard from context url: %1").arg(enc));
QApplication::clipboard()->setText(enc); QApplication::clipboard()->setText(enc);
} }
} }
@ -888,7 +896,6 @@ void HistoryList::copyContextText() {
QString contextMenuText = item->selectedText(FullItemSel); QString contextMenuText = item->selectedText(FullItemSel);
if (!contextMenuText.isEmpty()) { if (!contextMenuText.isEmpty()) {
DEBUG_LOG(("Setting text to clipboard from context menu: %1").arg(contextMenuText));
QApplication::clipboard()->setText(contextMenuText); QApplication::clipboard()->setText(contextMenuText);
} }
} }
@ -898,15 +905,21 @@ void HistoryList::resizeEvent(QResizeEvent *e) {
} }
QString HistoryList::getSelectedText() const { QString HistoryList::getSelectedText() const {
if (_selected.isEmpty()) return QString(); SelectedItems sel = _selected;
if (_selected.cbegin().value() != FullItemSel) {
return _selected.cbegin().key()->selectedText(_selected.cbegin().value()); if (_dragAction == Selecting && _dragSelFrom && _dragSelTo) {
applyDragSelection(&sel);
}
if (sel.isEmpty()) return QString();
if (sel.cbegin().value() != FullItemSel) {
return sel.cbegin().key()->selectedText(sel.cbegin().value());
} }
int32 fullSize = 0; int32 fullSize = 0;
QString timeFormat(qsl(", [dd.MM.yy hh:mm]\n")); QString timeFormat(qsl(", [dd.MM.yy hh:mm]\n"));
QMap<int32, QString> texts; QMap<int32, QString> texts;
for (SelectedItems::const_iterator i = _selected.cbegin(), e = _selected.cend(); i != e; ++i) { for (SelectedItems::const_iterator i = sel.cbegin(), e = sel.cend(); i != e; ++i) {
HistoryItem *item = i.key(); HistoryItem *item = i.key();
QString text, sel = item->selectedText(FullItemSel), time = item->date.toString(timeFormat); QString text, sel = item->selectedText(FullItemSel), time = item->date.toString(timeFormat);
int32 size = item->from()->name.size() + time.size() + sel.size(); int32 size = item->from()->name.size() + time.size() + sel.size();
@ -999,6 +1012,10 @@ void HistoryList::updateBotInfo(bool recount) {
} }
} }
bool HistoryList::wasSelectedText() const {
return _wasSelectedText;
}
void HistoryList::updateSize() { void HistoryList::updateSize() {
int32 ph = scrollArea->height(), minadd = 0; int32 ph = scrollArea->height(), minadd = 0;
ySkip = ph - (hist->height + st::historyPadding); ySkip = ph - (hist->height + st::historyPadding);
@ -1236,6 +1253,61 @@ void HistoryList::onUpdateSelected() {
if (item != _dragItem || (m - _dragStartPos).manhattanLength() >= QApplication::startDragDistance()) { if (item != _dragItem || (m - _dragStartPos).manhattanLength() >= QApplication::startDragDistance()) {
if (_dragAction == PrepareDrag) { if (_dragAction == PrepareDrag) {
_dragAction = Dragging; _dragAction = Dragging;
bool uponSelected = false;
if (_dragItem) {
bool afterDragSymbol;
uint16 symbol;
if (!_selected.isEmpty() && _selected.cbegin().value() == FullItemSel) {
uponSelected = _selected.contains(_dragItem);
} else {
_dragItem->getSymbol(symbol, afterDragSymbol, uponSelected, _dragStartPos.x(), _dragStartPos.y());
if (uponSelected) {
if (_selected.isEmpty() ||
_selected.cbegin().value() == FullItemSel ||
_selected.cbegin().key() != _dragItem
) {
uponSelected = false;
} else {
uint16 selFrom = (_selected.cbegin().value() >> 16) & 0xFFFF, selTo = _selected.cbegin().value() & 0xFFFF;
if (symbol < selFrom || symbol >= selTo) {
uponSelected = false;
}
}
}
}
}
QString sel;
QList<QUrl> urls;
if (uponSelected) {
sel = getSelectedText();
} else if (textlnkDown()) {
sel = textlnkDown()->encoded();
if (!sel.isEmpty() && sel.at(0) != '/' && sel.at(0) != '@' && sel.at(0) != '#') {
urls.push_back(QUrl::fromEncoded(sel.toUtf8()));
}
}
if (!sel.isEmpty()) {
updateDragSelection(0, 0, false);
historyWidget->noSelectingScroll();
QDrag *drag = new QDrag(App::wnd());
QMimeData *mimeData = new QMimeData;
mimeData->setText(sel);
if (!urls.isEmpty()) mimeData->setUrls(urls);
if (uponSelected && !_selected.isEmpty() && _selected.cbegin().value() == FullItemSel && cWideMode()) {
QStringList ids;
ids.reserve(_selected.size());
for (SelectedItems::const_iterator i = _selected.cbegin(), e = _selected.cend(); i != e; ++i) {
ids.push_back(QString::number(i.key()->id, 16));
}
mimeData->setData(qsl("application/x-td-forward-selected"), "1");
}
drag->setMimeData(mimeData);
drag->exec();
return;
}
} else if (_dragAction == PrepareSelect) { } else if (_dragAction == PrepareSelect) {
_dragAction = Selecting; _dragAction = Selecting;
} }
@ -1247,7 +1319,12 @@ void HistoryList::onUpdateSelected() {
uint16 second; uint16 second;
_dragItem->getSymbol(second, afterSymbol, uponSymbol, m.x(), m.y()); _dragItem->getSymbol(second, afterSymbol, uponSymbol, m.x(), m.y());
if (afterSymbol && _dragSelType == TextSelectLetters) ++second; if (afterSymbol && _dragSelType == TextSelectLetters) ++second;
_selected[_dragItem] = _dragItem->adjustSelection(qMin(second, _dragSymbol), qMax(second, _dragSymbol), _dragSelType); uint32 selState = _dragItem->adjustSelection(qMin(second, _dragSymbol), qMax(second, _dragSymbol), _dragSelType);
_selected[_dragItem] = selState;
if (!_wasSelectedText && (selState == FullItemSel || (selState & 0xFFFF) != ((selState >> 16) & 0xFFFF))) {
_wasSelectedText = true;
setFocus();
}
updateDragSelection(0, 0, false); updateDragSelection(0, 0, false);
} else { } else {
bool selectingDown = (_dragItem->block()->y < item->block()->y) || ((_dragItem->block() == item->block()) && (_dragItem->y < item->y || (_dragItem == item && _dragStartPos.y() < m.y()))); bool selectingDown = (_dragItem->block()->y < item->block()->y) || ((_dragItem->block() == item->block()) && (_dragItem->y < item->y || (_dragItem == item && _dragStartPos.y() < m.y())));
@ -1316,6 +1393,10 @@ void HistoryList::updateDragSelection(HistoryItem *dragSelFrom, HistoryItem *dra
qSwap(_dragSelFrom, _dragSelTo); qSwap(_dragSelFrom, _dragSelTo);
} }
_dragSelecting = dragSelecting; _dragSelecting = dragSelecting;
if (!_wasSelectedText && _dragSelFrom && _dragSelTo && _dragSelecting) {
_wasSelectedText = true;
setFocus();
}
force = true; force = true;
} }
if (!force) return; if (!force) return;
@ -1324,9 +1405,14 @@ void HistoryList::updateDragSelection(HistoryItem *dragSelFrom, HistoryItem *dra
} }
void HistoryList::applyDragSelection() { void HistoryList::applyDragSelection() {
if (!_selected.isEmpty() && _selected.cbegin().value() != FullItemSel) { applyDragSelection(&_selected);
_selected.clear(); }
void HistoryList::applyDragSelection(SelectedItems *toItems) const {
if (!toItems->isEmpty() && toItems->cbegin().value() != FullItemSel) {
toItems->clear();
} }
int32 fromy = _dragSelFrom->y + _dragSelFrom->block()->y, toy = _dragSelTo->y + _dragSelTo->block()->y + _dragSelTo->height(); int32 fromy = _dragSelFrom->y + _dragSelFrom->block()->y, toy = _dragSelTo->y + _dragSelTo->block()->y + _dragSelTo->height();
if (_dragSelecting) { if (_dragSelecting) {
int32 fromblock = hist->indexOf(_dragSelFrom->block()), fromitem = _dragSelFrom->block()->indexOf(_dragSelFrom); int32 fromblock = hist->indexOf(_dragSelFrom->block()), fromitem = _dragSelFrom->block()->indexOf(_dragSelFrom);
@ -1336,35 +1422,34 @@ void HistoryList::applyDragSelection() {
HistoryBlock *block = (*hist)[fromblock]; HistoryBlock *block = (*hist)[fromblock];
for (int32 cnt = (fromblock < toblock) ? block->size() : (toitem + 1); fromitem < cnt; ++fromitem) { for (int32 cnt = (fromblock < toblock) ? block->size() : (toitem + 1); fromitem < cnt; ++fromitem) {
HistoryItem *item = (*block)[fromitem]; HistoryItem *item = (*block)[fromitem];
SelectedItems::iterator i = _selected.find(item); SelectedItems::iterator i = toItems->find(item);
if (item->id > 0 && !item->serviceMsg()) { if (item->id > 0 && !item->serviceMsg()) {
if (i == _selected.cend()) { if (i == toItems->cend()) {
if (_selected.size() >= MaxSelectedItems) break; if (toItems->size() >= MaxSelectedItems) break;
_selected.insert(item, FullItemSel); toItems->insert(item, FullItemSel);
} else if (i.value() != FullItemSel) { } else if (i.value() != FullItemSel) {
*i = FullItemSel; *i = FullItemSel;
} }
} else { } else {
if (i != _selected.cend()) { if (i != toItems->cend()) {
_selected.erase(i); toItems->erase(i);
} }
} }
} }
if (_selected.size() >= MaxSelectedItems) break; if (toItems->size() >= MaxSelectedItems) break;
fromitem = 0; fromitem = 0;
} }
} }
} else { } else {
for (SelectedItems::iterator i = _selected.begin(); i != _selected.cend(); ) { for (SelectedItems::iterator i = toItems->begin(); i != toItems->cend();) {
int32 iy = i.key()->y + i.key()->block()->y; int32 iy = i.key()->y + i.key()->block()->y;
if (iy >= fromy && iy < toy) { if (iy >= fromy && iy < toy) {
i = _selected.erase(i); i = toItems->erase(i);
} else { } else {
++i; ++i;
} }
} }
} }
_dragSelFrom = _dragSelTo = 0;
} }
void HistoryList::showLinkTip() { void HistoryList::showLinkTip() {
@ -1579,9 +1664,9 @@ bool BotKeyboard::updateMarkup(HistoryItem *to) {
clearSelection(); clearSelection();
_btns.clear(); _btns.clear();
const ReplyMarkup &markup(App::replyMarkup(to->id)); const ReplyMarkup &markup(App::replyMarkup(to->id));
_forceReply = markup.flags | MTPDreplyKeyboardMarkup_flag_FORCE_REPLY; _forceReply = markup.flags & MTPDreplyKeyboardMarkup_flag_FORCE_REPLY;
_maximizeSize = !(markup.flags & MTPDreplyKeyboardMarkup_flag_resize); _maximizeSize = !(markup.flags & MTPDreplyKeyboardMarkup_flag_resize);
_singleUse = markup.flags & MTPDreplyKeyboardMarkup_flag_single_use; _singleUse = _forceReply || (markup.flags & MTPDreplyKeyboardMarkup_flag_single_use);
const ReplyMarkup::Commands &commands(markup.commands); const ReplyMarkup::Commands &commands(markup.commands);
if (!commands.isEmpty()) { if (!commands.isEmpty()) {
@ -2034,6 +2119,8 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent)
, _attachEmoji(this, st::btnAttachEmoji) , _attachEmoji(this, st::btnAttachEmoji)
, _kbShow(this, st::btnBotKbShow) , _kbShow(this, st::btnBotKbShow)
, _kbHide(this, st::btnBotKbHide) , _kbHide(this, st::btnBotKbHide)
, _cmdStart(this, st::btnBotCmdStart)
, _cmdStartShown(false)
, _field(this, st::taMsgField, lang(lng_message_ph)) , _field(this, st::taMsgField, lang(lng_message_ph))
, _recordAnim(animFunc(this, &HistoryWidget::recordStep)) , _recordAnim(animFunc(this, &HistoryWidget::recordStep))
, _recordingAnim(animFunc(this, &HistoryWidget::recordingStep)) , _recordingAnim(animFunc(this, &HistoryWidget::recordingStep))
@ -2126,7 +2213,7 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent)
_toHistoryEnd.installEventFilter(this); _toHistoryEnd.installEventFilter(this);
_attachMention.hide(); _attachMention.hide();
connect(&_attachMention, SIGNAL(chosen(QString)), &_field, SLOT(onMentionHashtagOrBotCommandInsert(QString))); connect(&_attachMention, SIGNAL(chosen(QString)), this, SLOT(onMentionHashtagOrBotCommandInsert(QString)));
_field.installEventFilter(&_attachMention); _field.installEventFilter(&_attachMention);
_field.hide(); _field.hide();
@ -2139,6 +2226,7 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent)
_attachEmoji.hide(); _attachEmoji.hide();
_kbShow.hide(); _kbShow.hide();
_kbHide.hide(); _kbHide.hide();
_cmdStart.hide();
_attachDocument.installEventFilter(&_attachType); _attachDocument.installEventFilter(&_attachType);
_attachPhoto.installEventFilter(&_attachType); _attachPhoto.installEventFilter(&_attachType);
@ -2146,6 +2234,7 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent)
connect(&_kbShow, SIGNAL(clicked()), this, SLOT(onKbToggle())); connect(&_kbShow, SIGNAL(clicked()), this, SLOT(onKbToggle()));
connect(&_kbHide, SIGNAL(clicked()), this, SLOT(onKbToggle())); connect(&_kbHide, SIGNAL(clicked()), this, SLOT(onKbToggle()));
connect(&_cmdStart, SIGNAL(clicked()), this, SLOT(onCmdStart()));
connect(_attachType.addButton(new IconedButton(this, st::dropdownAttachDocument, lang(lng_attach_file))), SIGNAL(clicked()), this, SLOT(onDocumentSelect())); connect(_attachType.addButton(new IconedButton(this, st::dropdownAttachDocument, lang(lng_attach_file))), SIGNAL(clicked()), this, SLOT(onDocumentSelect()));
connect(_attachType.addButton(new IconedButton(this, st::dropdownAttachPhoto, lang(lng_attach_photo))), SIGNAL(clicked()), this, SLOT(onPhotoSelect())); connect(_attachType.addButton(new IconedButton(this, st::dropdownAttachPhoto, lang(lng_attach_photo))), SIGNAL(clicked()), this, SLOT(onPhotoSelect()));
@ -2164,6 +2253,15 @@ void HistoryWidget::start() {
connect(App::api(), SIGNAL(fullPeerUpdated(PeerData*)), this, SLOT(onFullPeerUpdated(PeerData*))); connect(App::api(), SIGNAL(fullPeerUpdated(PeerData*)), this, SLOT(onFullPeerUpdated(PeerData*)));
} }
void HistoryWidget::onMentionHashtagOrBotCommandInsert(QString str) {
if (str.at(0) == '/') { // bot command
App::sendBotCommand(str);
setFieldText(_field.getLastText().mid(_field.textCursor().position()));
} else {
_field.onMentionHashtagOrBotCommandInsert(str);
}
}
void HistoryWidget::onTextChange() { void HistoryWidget::onTextChange() {
updateTyping(); updateTyping();
@ -2182,6 +2280,11 @@ void HistoryWidget::onTextChange() {
a_recordCancel = anim::cvalue(st::recordCancel->c, st::recordCancel->c); a_recordCancel = anim::cvalue(st::recordCancel->c, st::recordCancel->c);
} }
} }
if (updateCmdStartShown()) {
updateControlsVisibility();
resizeEvent(0);
update();
}
if (!hist || _synthedTextUpdate) return; if (!hist || _synthedTextUpdate) return;
_saveDraftText = true; _saveDraftText = true;
@ -2269,7 +2372,7 @@ void HistoryWidget::activate() {
} }
} }
if (_list) { if (_list) {
if (_selCount || _recording || isBotStart()) { if (_selCount || (_list && _list->wasSelectedText()) || _recording || isBotStart()) {
_list->setFocus(); _list->setFocus();
} else { } else {
_field.setFocus(); _field.setFocus();
@ -2574,6 +2677,7 @@ void HistoryWidget::setKbWasHidden() {
_kbScroll.hide(); _kbScroll.hide();
_attachEmoji.show(); _attachEmoji.show();
_kbHide.hide(); _kbHide.hide();
_cmdStart.hide();
_kbShow.show(); _kbShow.show();
} }
_field.setMaxHeight(st::maxFieldHeight); _field.setMaxHeight(st::maxFieldHeight);
@ -2710,6 +2814,8 @@ void HistoryWidget::showPeer(const PeerId &peer, MsgId msgId, bool force, bool l
App::contextItem(0); App::contextItem(0);
App::mousedItem(0); App::mousedItem(0);
_kbWasHidden = false;
if (peer) { if (peer) {
App::forgetMedia(); App::forgetMedia();
serviceImageCacheSize = imageCacheSize(); serviceImageCacheSize = imageCacheSize();
@ -2737,6 +2843,7 @@ void HistoryWidget::showPeer(const PeerId &peer, MsgId msgId, bool force, bool l
_scroll.setWidget(_list); _scroll.setWidget(_list);
_list->show(); _list->show();
updateBotKeyboard();
checkUnreadLoaded(); checkUnreadLoaded();
App::main()->peerUpdated(histPeer); App::main()->peerUpdated(histPeer);
@ -2774,12 +2881,10 @@ void HistoryWidget::showPeer(const PeerId &peer, MsgId msgId, bool force, bool l
connect(&_scroll, SIGNAL(geometryChanged()), _list, SLOT(onParentGeometryChanged())); connect(&_scroll, SIGNAL(geometryChanged()), _list, SLOT(onParentGeometryChanged()));
connect(&_scroll, SIGNAL(scrolled()), _list, SLOT(onUpdateSelected())); connect(&_scroll, SIGNAL(scrolled()), _list, SLOT(onUpdateSelected()));
} else { } else {
updateBotKeyboard();
updateControlsVisibility(); updateControlsVisibility();
} }
_kbWasHidden = false;
updateBotKeyboard();
emit peerShown(histPeer); emit peerShown(histPeer);
App::main()->topBar()->update(); App::main()->topBar()->update();
update(); update();
@ -2825,6 +2930,7 @@ void HistoryWidget::updateControlsVisibility() {
_toHistoryEnd.hide(); _toHistoryEnd.hide();
_kbShow.hide(); _kbShow.hide();
_kbHide.hide(); _kbHide.hide();
_cmdStart.hide();
_attachType.hide(); _attachType.hide();
_emojiPan.hide(); _emojiPan.hide();
return; return;
@ -2845,6 +2951,7 @@ void HistoryWidget::updateControlsVisibility() {
_attachEmoji.hide(); _attachEmoji.hide();
_kbShow.hide(); _kbShow.hide();
_kbHide.hide(); _kbHide.hide();
_cmdStart.hide();
_attachDocument.hide(); _attachDocument.hide();
_attachPhoto.hide(); _attachPhoto.hide();
_kbScroll.hide(); _kbScroll.hide();
@ -2867,6 +2974,7 @@ void HistoryWidget::updateControlsVisibility() {
_attachEmoji.hide(); _attachEmoji.hide();
_kbShow.hide(); _kbShow.hide();
_kbHide.hide(); _kbHide.hide();
_cmdStart.hide();
_attachDocument.hide(); _attachDocument.hide();
_attachPhoto.hide(); _attachPhoto.hide();
if (_kbShown) { if (_kbShown) {
@ -2881,19 +2989,27 @@ void HistoryWidget::updateControlsVisibility() {
_attachEmoji.hide(); _attachEmoji.hide();
_kbHide.show(); _kbHide.show();
_kbShow.hide(); _kbShow.hide();
_cmdStart.hide();
} else if (_kbReplyTo) { } else if (_kbReplyTo) {
_kbScroll.hide(); _kbScroll.hide();
_attachEmoji.show(); _attachEmoji.show();
_kbHide.hide(); _kbHide.hide();
_kbShow.hide(); _kbShow.hide();
_cmdStart.hide();
} else { } else {
_kbScroll.hide(); _kbScroll.hide();
_attachEmoji.show(); _attachEmoji.show();
_kbHide.hide(); _kbHide.hide();
if (_keyboard.hasMarkup() || _keyboard.forceReply()) { if (_keyboard.hasMarkup()) {
_kbShow.show(); _kbShow.show();
_cmdStart.hide();
} else { } else {
_kbShow.hide(); _kbShow.hide();
if (_cmdStartShown) {
_cmdStart.show();
} else {
_cmdStart.hide();
}
} }
} }
if (cDefaultAttach() == dbidaPhoto) { if (cDefaultAttach() == dbidaPhoto) {
@ -2923,6 +3039,7 @@ void HistoryWidget::updateControlsVisibility() {
_attachEmoji.hide(); _attachEmoji.hide();
_kbShow.hide(); _kbShow.hide();
_kbHide.hide(); _kbHide.hide();
_cmdStart.hide();
_attachType.hide(); _attachType.hide();
_emojiPan.hide(); _emojiPan.hide();
if (!_field.isHidden()) { if (!_field.isHidden()) {
@ -2948,6 +3065,7 @@ void HistoryWidget::updateControlsVisibility() {
_attachEmoji.hide(); _attachEmoji.hide();
_kbShow.hide(); _kbShow.hide();
_kbHide.hide(); _kbHide.hide();
_cmdStart.hide();
_attachType.hide(); _attachType.hide();
_emojiPan.hide(); _emojiPan.hide();
_replyForwardPreviewCancel.hide(); _replyForwardPreviewCancel.hide();
@ -3302,6 +3420,7 @@ void HistoryWidget::onSend(bool ctrlShiftEnter, MsgId replyTo) {
if (!_attachMention.isHidden()) _attachMention.hideStart(); if (!_attachMention.isHidden()) _attachMention.hideStart();
if (!_attachType.isHidden()) _attachType.hideStart(); if (!_attachType.isHidden()) _attachType.hideStart();
if (!_emojiPan.isHidden()) _emojiPan.hideStart(); if (!_emojiPan.isHidden()) _emojiPan.hideStart();
} else if (App::main()->hasForwardingItems()) { } else if (App::main()->hasForwardingItems()) {
App::main()->readServerHistory(hist, false); App::main()->readServerHistory(hist, false);
hist->loadAround(0); hist->loadAround(0);
@ -3311,6 +3430,8 @@ void HistoryWidget::onSend(bool ctrlShiftEnter, MsgId replyTo) {
if (replyTo < 0) cancelReply(lastKeyboardUsed); if (replyTo < 0) cancelReply(lastKeyboardUsed);
if (_previewData && _previewData->pendingTill) previewCancel(); if (_previewData && _previewData->pendingTill) previewCancel();
_field.setFocus(); _field.setFocus();
if (!_keyboard.hasMarkup() && _keyboard.forceReply() && !_kbReplyTo) onKbToggle();
} }
void HistoryWidget::onBotStart() { void HistoryWidget::onBotStart() {
@ -3326,7 +3447,7 @@ void HistoryWidget::onBotStart() {
MTP::send(MTPmessages_StartBot(histPeer->asUser()->inputUser, MTP_int(0), MTP_long(randomId), MTP_string(token)), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcFail(&MainWidget::addParticipantFail, histPeer->asUser())); MTP::send(MTPmessages_StartBot(histPeer->asUser()->inputUser, MTP_int(0), MTP_long(randomId), MTP_string(token)), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcFail(&MainWidget::addParticipantFail, histPeer->asUser()));
histPeer->asUser()->botInfo->startToken = QString(); histPeer->asUser()->botInfo->startToken = QString();
if (_keyboard.hasMarkup() || _keyboard.forceReply()) { if (_keyboard.hasMarkup()) {
if (_keyboard.singleUse() && _keyboard.forMsgId() == hist->lastKeyboardId && hist->lastKeyboardUsed) _kbWasHidden = true; if (_keyboard.singleUse() && _keyboard.forMsgId() == hist->lastKeyboardId && hist->lastKeyboardUsed) _kbWasHidden = true;
if (!_kbWasHidden) _kbShown = _keyboard.hasMarkup(); if (!_kbWasHidden) _kbShown = _keyboard.hasMarkup();
} }
@ -3415,6 +3536,7 @@ void HistoryWidget::animShow(const QPixmap &bgAnimCache, const QPixmap &bgAnimTo
_attachMention.hide(); _attachMention.hide();
_kbShow.hide(); _kbShow.hide();
_kbHide.hide(); _kbHide.hide();
_cmdStart.hide();
_field.hide(); _field.hide();
_replyForwardPreviewCancel.hide(); _replyForwardPreviewCancel.hide();
_send.hide(); _send.hide();
@ -3783,10 +3905,26 @@ void HistoryWidget::updateDragAreas() {
} }
bool HistoryWidget::isBotStart() const { bool HistoryWidget::isBotStart() const {
if (histPeer->chat || !histPeer->asUser()->botInfo) return false; if (!hist || !histPeer || histPeer->chat || !histPeer->asUser()->botInfo) return false;
return !histPeer->asUser()->botInfo->startToken.isEmpty() || (hist->isEmpty() && !hist->lastMsg); return !histPeer->asUser()->botInfo->startToken.isEmpty() || (hist->isEmpty() && !hist->lastMsg);
} }
bool HistoryWidget::updateCmdStartShown() {
bool cmdStartShown = false;
if (hist && histPeer && ((histPeer->chat && histPeer->asChat()->botStatus > 0) || (!histPeer->chat && histPeer->asUser()->botInfo))) {
if (!isBotStart() && !_keyboard.hasMarkup() && !_keyboard.forceReply()) {
if (_field.getLastText().isEmpty()) {
cmdStartShown = true;
}
}
}
if (_cmdStartShown != cmdStartShown) {
_cmdStartShown = cmdStartShown;
return true;
}
return false;
}
void HistoryWidget::dropEvent(QDropEvent *e) { void HistoryWidget::dropEvent(QDropEvent *e) {
_attachDrag = DragStateNone; _attachDrag = DragStateNone;
updateDragAreas(); updateDragAreas();
@ -3805,20 +3943,29 @@ void HistoryWidget::onDocumentDrop(QDropEvent *e) {
void HistoryWidget::onKbToggle(bool manual) { void HistoryWidget::onKbToggle(bool manual) {
if (_kbShown || _kbReplyTo) { if (_kbShown || _kbReplyTo) {
_kbHide.hide(); _kbHide.hide();
_kbShow.show(); if (_kbShown) {
_kbScroll.hide(); _kbShow.show();
_kbShown = false; if (manual) _kbWasHidden = true;
_field.setMaxHeight(st::maxFieldHeight); _kbScroll.hide();
_kbShown = false;
_kbReplyTo = 0; _field.setMaxHeight(st::maxFieldHeight);
if (!App::main()->hasForwardingItems() && (!_previewData || _previewData->pendingTill < 0) && !_replyToId) {
_replyForwardPreviewCancel.hide(); _kbReplyTo = 0;
if (!App::main()->hasForwardingItems() && (!_previewData || _previewData->pendingTill < 0) && !_replyToId) {
_replyForwardPreviewCancel.hide();
}
} else {
if (hist) {
hist->clearLastKeyboard();
}
updateBotKeyboard();
} }
if (manual) _kbWasHidden = true;
} else if (!_keyboard.hasMarkup() && _keyboard.forceReply()) { } else if (!_keyboard.hasMarkup() && _keyboard.forceReply()) {
_kbHide.hide(); _kbHide.hide();
_kbShow.hide(); _kbShow.hide();
_cmdStart.show();
_kbScroll.hide(); _kbScroll.hide();
_kbShown = false; _kbShown = false;
@ -3857,6 +4004,11 @@ void HistoryWidget::onKbToggle(bool manual) {
updateField(); updateField();
} }
void HistoryWidget::onCmdStart() {
setFieldText(qsl("/"));
_field.moveCursor(QTextCursor::End);
}
void HistoryWidget::onPhotoDrop(QDropEvent *e) { void HistoryWidget::onPhotoDrop(QDropEvent *e) {
if (!hist) return; if (!hist) return;
@ -4029,6 +4181,7 @@ void HistoryWidget::onFieldResize() {
_attachEmoji.move(_send.x() - _attachEmoji.width(), height() - kbh - _attachEmoji.height()); _attachEmoji.move(_send.x() - _attachEmoji.width(), height() - kbh - _attachEmoji.height());
_kbShow.move(_attachEmoji.x() - _kbShow.width(), height() - kbh - _kbShow.height()); _kbShow.move(_attachEmoji.x() - _kbShow.width(), height() - kbh - _kbShow.height());
_kbHide.move(_attachEmoji.x(), _attachEmoji.y()); _kbHide.move(_attachEmoji.x(), _attachEmoji.y());
_cmdStart.move(_attachEmoji.x() - _cmdStart.width(), height() - kbh - _cmdStart.height());
_attachType.move(0, _attachDocument.y() - _attachType.height()); _attachType.move(0, _attachDocument.y() - _attachType.height());
_emojiPan.move(width() - _emojiPan.width(), _attachEmoji.y() - _emojiPan.height()); _emojiPan.move(width() - _emojiPan.width(), _attachEmoji.y() - _emojiPan.height());
@ -4391,7 +4544,8 @@ void HistoryWidget::resizeEvent(QResizeEvent *e) {
_replyForwardPreviewCancel.move(width() - _replyForwardPreviewCancel.width(), _field.y() - st::sendPadding - _replyForwardPreviewCancel.height()); _replyForwardPreviewCancel.move(width() - _replyForwardPreviewCancel.width(), _field.y() - st::sendPadding - _replyForwardPreviewCancel.height());
updateListSize(); updateListSize();
_field.resize(width() - _send.width() - _attachDocument.width() - _attachEmoji.width() - ((_kbShown || (!_keyboard.hasMarkup() && !_keyboard.forceReply())) ? 0 : _kbShow.width()), _field.height()); bool kbShowShown = hist && !_kbShown && _keyboard.hasMarkup();
_field.resize(width() - _send.width() - _attachDocument.width() - _attachEmoji.width() - (kbShowShown ? _kbShow.width() : 0) - (_cmdStartShown ? _cmdStart.width() : 0), _field.height());
_toHistoryEnd.move((width() - _toHistoryEnd.width()) / 2, _scroll.y() + _scroll.height() - _toHistoryEnd.height() - st::historyToEndSkip); _toHistoryEnd.move((width() - _toHistoryEnd.width()) / 2, _scroll.y() + _scroll.height() - _toHistoryEnd.height() - st::historyToEndSkip);
@ -4400,6 +4554,7 @@ void HistoryWidget::resizeEvent(QResizeEvent *e) {
_attachEmoji.move(_send.x() - _attachEmoji.width(), height() - kbh - _attachEmoji.height()); _attachEmoji.move(_send.x() - _attachEmoji.width(), height() - kbh - _attachEmoji.height());
_kbShow.move(_attachEmoji.x() - _kbShow.width(), height() - kbh - _kbShow.height()); _kbShow.move(_attachEmoji.x() - _kbShow.width(), height() - kbh - _kbShow.height());
_kbHide.move(_attachEmoji.x(), _attachEmoji.y()); _kbHide.move(_attachEmoji.x(), _attachEmoji.y());
_cmdStart.move(_attachEmoji.x() - _cmdStart.width(), height() - kbh - _cmdStart.height());
_attachType.move(0, _attachDocument.y() - _attachType.height()); _attachType.move(0, _attachDocument.y() - _attachType.height());
_emojiPan.move(width() - _emojiPan.width(), _attachEmoji.y() - _emojiPan.height()); _emojiPan.move(width() - _emojiPan.width(), _attachEmoji.y() - _emojiPan.height());
@ -4575,11 +4730,12 @@ void HistoryWidget::updateBotKeyboard() {
} else { } else {
changed = _keyboard.updateMarkup(hist->lastKeyboardId ? App::histItemById(hist->lastKeyboardId) : 0); changed = _keyboard.updateMarkup(hist->lastKeyboardId ? App::histItemById(hist->lastKeyboardId) : 0);
} }
updateCmdStartShown();
if (!changed) return; if (!changed) return;
bool hasMarkup = _keyboard.hasMarkup(), forceReply = _keyboard.forceReply() && !_replyTo; bool hasMarkup = _keyboard.hasMarkup(), forceReply = _keyboard.forceReply() && !_replyTo;
if (hasMarkup || forceReply) { if (hasMarkup || forceReply) {
if (_keyboard.singleUse() && _keyboard.forMsgId() == hist->lastKeyboardId && hist->lastKeyboardUsed) _kbWasHidden = true; if (_keyboard.singleUse() && _keyboard.hasMarkup() && _keyboard.forMsgId() == hist->lastKeyboardId && hist->lastKeyboardUsed) _kbWasHidden = true;
if (!isBotStart() && (wasVisible || _replyTo || (_field.getLastText().isEmpty() && !_kbWasHidden))) { if (!isBotStart() && (wasVisible || _replyTo || (_field.getLastText().isEmpty() && !_kbWasHidden))) {
if (!_showAnim.animating()) { if (!_showAnim.animating()) {
if (hasMarkup) { if (hasMarkup) {
@ -4592,6 +4748,7 @@ void HistoryWidget::updateBotKeyboard() {
_kbHide.hide(); _kbHide.hide();
} }
_kbShow.hide(); _kbShow.hide();
_cmdStart.hide();
} }
int32 maxh = hasMarkup ? qMin(_keyboard.height(), int(st::maxFieldHeight) - (int(st::maxFieldHeight) / 2)) : 0; int32 maxh = hasMarkup ? qMin(_keyboard.height(), int(st::maxFieldHeight) - (int(st::maxFieldHeight) / 2)) : 0;
_field.setMaxHeight(st::maxFieldHeight - maxh); _field.setMaxHeight(st::maxFieldHeight - maxh);
@ -4608,6 +4765,7 @@ void HistoryWidget::updateBotKeyboard() {
_attachEmoji.show(); _attachEmoji.show();
_kbHide.hide(); _kbHide.hide();
_kbShow.show(); _kbShow.show();
_cmdStart.hide();
} }
_field.setMaxHeight(st::maxFieldHeight); _field.setMaxHeight(st::maxFieldHeight);
_kbShown = false; _kbShown = false;
@ -4622,6 +4780,7 @@ void HistoryWidget::updateBotKeyboard() {
_attachEmoji.show(); _attachEmoji.show();
_kbHide.hide(); _kbHide.hide();
_kbShow.hide(); _kbShow.hide();
_cmdStart.show();
} }
_field.setMaxHeight(st::maxFieldHeight); _field.setMaxHeight(st::maxFieldHeight);
_kbShown = false; _kbShown = false;
@ -4822,8 +4981,9 @@ void HistoryWidget::cancelReply(bool lastKeyboardUsed) {
onDraftSave(); onDraftSave();
} }
if (_keyboard.singleUse() && _keyboard.forceReply() && lastKeyboardUsed) { if (_keyboard.singleUse() && _keyboard.forceReply() && lastKeyboardUsed) {
if (_kbReplyTo) onKbToggle(false); if (_kbReplyTo) {
hist->lastKeyboardUsed = true; onKbToggle(false);
}
} }
} }
@ -4979,6 +5139,11 @@ void HistoryWidget::onFullPeerUpdated(PeerData *data) {
checkMentionDropdown(); checkMentionDropdown();
_list->updateBotInfo(); _list->updateBotInfo();
} }
if (updateCmdStartShown()) {
updateControlsVisibility();
resizeEvent(0);
update();
}
} }
void HistoryWidget::peerUpdated(PeerData *data) { void HistoryWidget::peerUpdated(PeerData *data) {
@ -5096,7 +5261,7 @@ void HistoryWidget::updateTopBarSelection() {
updateControlsVisibility(); updateControlsVisibility();
updateListSize(); updateListSize();
if (!App::wnd()->layerShown() && !App::passcoded()) { if (!App::wnd()->layerShown() && !App::passcoded()) {
if (_selCount || _recording || isBotStart()) { if (_selCount || (_list && _list->wasSelectedText()) || _recording || isBotStart()) {
_list->setFocus(); _list->setFocus();
} else { } else {
_field.setFocus(); _field.setFocus();

View File

@ -81,6 +81,8 @@ public:
void updateBotInfo(bool recount = true); void updateBotInfo(bool recount = true);
bool wasSelectedText() const;
~HistoryList(); ~HistoryList();
public slots: public slots:
@ -115,7 +117,6 @@ private:
HistoryItem *prevItem(HistoryItem *item); HistoryItem *prevItem(HistoryItem *item);
HistoryItem *nextItem(HistoryItem *item); HistoryItem *nextItem(HistoryItem *item);
void updateDragSelection(HistoryItem *dragSelFrom, HistoryItem *dragSelTo, bool dragSelecting, bool force = false); void updateDragSelection(HistoryItem *dragSelFrom, HistoryItem *dragSelTo, bool dragSelecting, bool force = false);
void applyDragSelection();
History *hist; History *hist;
@ -133,6 +134,9 @@ private:
Qt::CursorShape _cursor; Qt::CursorShape _cursor;
typedef QMap<HistoryItem*, uint32> SelectedItems; typedef QMap<HistoryItem*, uint32> SelectedItems;
SelectedItems _selected; SelectedItems _selected;
void applyDragSelection();
void applyDragSelection(SelectedItems *toItems) const;
enum DragAction { enum DragAction {
NoDrag = 0x00, NoDrag = 0x00,
PrepareDrag = 0x01, PrepareDrag = 0x01,
@ -154,6 +158,7 @@ private:
HistoryItem *_dragSelFrom, *_dragSelTo; HistoryItem *_dragSelFrom, *_dragSelTo;
bool _dragSelecting; bool _dragSelecting;
bool _wasSelectedText; // was some text selected in current drag action
bool _touchScroll, _touchSelect, _touchInProgress; bool _touchScroll, _touchSelect, _touchInProgress;
QPoint _touchStart, _touchPrevPos, _touchPos; QPoint _touchStart, _touchPrevPos, _touchPos;
@ -460,6 +465,8 @@ public:
bool eventFilter(QObject *obj, QEvent *e); bool eventFilter(QObject *obj, QEvent *e);
void updateBotKeyboard(); void updateBotKeyboard();
DragState getDragState(const QMimeData *d);
~HistoryWidget(); ~HistoryWidget();
signals: signals:
@ -506,6 +513,7 @@ public slots:
void onDocumentDrop(QDropEvent *e); void onDocumentDrop(QDropEvent *e);
void onKbToggle(bool manual = true); void onKbToggle(bool manual = true);
void onCmdStart();
void onPhotoReady(); void onPhotoReady();
void onSendConfirmed(); void onSendConfirmed();
@ -514,6 +522,7 @@ public slots:
void showPeer(const PeerId &peer, MsgId msgId = 0, bool force = false, bool leaveActive = false); void showPeer(const PeerId &peer, MsgId msgId = 0, bool force = false, bool leaveActive = false);
void clearLoadingAround(); void clearLoadingAround();
void activate(); void activate();
void onMentionHashtagOrBotCommandInsert(QString str);
void onTextChange(); void onTextChange();
void onStickerSend(DocumentData *sticker); void onStickerSend(DocumentData *sticker);
@ -591,7 +600,6 @@ private:
void setFieldText(const QString &text); void setFieldText(const QString &text);
QStringList getMediasFromMime(const QMimeData *d); QStringList getMediasFromMime(const QMimeData *d);
DragState getDragState(const QMimeData *d);
void updateDragAreas(); void updateDragAreas();
@ -616,9 +624,11 @@ private:
MentionsDropdown _attachMention; MentionsDropdown _attachMention;
bool isBotStart() const; bool isBotStart() const;
bool updateCmdStartShown();
FlatButton _send, _botStart; FlatButton _send, _botStart;
IconedButton _attachDocument, _attachPhoto, _attachEmoji, _kbShow, _kbHide; IconedButton _attachDocument, _attachPhoto, _attachEmoji, _kbShow, _kbHide, _cmdStart;
bool _cmdStartShown;
MessageField _field; MessageField _field;
Animation _recordAnim, _recordingAnim; Animation _recordAnim, _recordingAnim;
bool _recording, _inRecord, _inField, _inReply; bool _recording, _inRecord, _inField, _inReply;

View File

@ -694,6 +694,10 @@ void MainWidget::dialogsActivate() {
dialogs.activate(); dialogs.activate();
} }
DragState MainWidget::getDragState(const QMimeData *mime) {
return history.getDragState(mime);
}
bool MainWidget::leaveChatFailed(PeerData *peer, const RPCError &error) { bool MainWidget::leaveChatFailed(PeerData *peer, const RPCError &error) {
if (error.type().startsWith(qsl("FLOOD_WAIT_"))) return false; if (error.type().startsWith(qsl("FLOOD_WAIT_"))) return false;

View File

@ -262,6 +262,8 @@ public:
void focusPeerSelect(); void focusPeerSelect();
void dialogsActivate(); void dialogsActivate();
DragState getDragState(const QMimeData *mime);
bool leaveChatFailed(PeerData *peer, const RPCError &e); bool leaveChatFailed(PeerData *peer, const RPCError &e);
void deleteHistory(PeerData *peer, const MTPUpdates &updates); void deleteHistory(PeerData *peer, const MTPUpdates &updates);
void deleteHistoryPart(PeerData *peer, const MTPmessages_AffectedHistory &result); void deleteHistoryPart(PeerData *peer, const MTPmessages_AffectedHistory &result);

View File

@ -300,7 +300,6 @@ void ProfileInner::onMediaAudios() {
} }
void ProfileInner::onInvitationLink() { void ProfileInner::onInvitationLink() {
DEBUG_LOG(("Setting text to clipboard from invite url: %1").arg(_peerChat->invitationUrl));
QApplication::clipboard()->setText(_peerChat->invitationUrl); QApplication::clipboard()->setText(_peerChat->invitationUrl);
App::wnd()->showLayer(new ConfirmBox(lang(lng_group_invite_copied), true)); App::wnd()->showLayer(new ConfirmBox(lang(lng_group_invite_copied), true));
} }
@ -512,7 +511,7 @@ void ProfileInner::paintEvent(QPaintEvent *e) {
p.setPen(st::black->p); p.setPen(st::black->p);
p.drawText(_left + st::profilePhotoSize + st::profileStatusLeft, top + st::profileStatusTop + st::linkFont->ascent, '@' + _peerUser->username); p.drawText(_left + st::profilePhotoSize + st::profileStatusLeft, top + st::profileStatusTop + st::linkFont->ascent, '@' + _peerUser->username);
} }
p.setPen((_peerUser && App::onlineColorUse(_peerUser->onlineTill, l_time) ? st::profileOnlineColor : st::profileOfflineColor)->p); p.setPen((_peerUser && App::onlineColorUse(_peerUser, l_time) ? st::profileOnlineColor : st::profileOfflineColor)->p);
p.drawText(_left + st::profilePhotoSize + st::profileStatusLeft, top + addbyname + st::profileStatusTop + st::linkFont->ascent, _onlineText); p.drawText(_left + st::profilePhotoSize + st::profileStatusLeft, top + addbyname + st::profileStatusTop + st::linkFont->ascent, _onlineText);
if (_chatAdmin && !_peerChat->invitationUrl.isEmpty()) { if (_chatAdmin && !_peerChat->invitationUrl.isEmpty()) {
p.setPen(st::black->p); p.setPen(st::black->p);
@ -643,7 +642,7 @@ void ProfileInner::paintEvent(QPaintEvent *e) {
p.setFont(st::linkFont->f); p.setFont(st::linkFont->f);
data->name.drawElided(p, _left + st::profileListPhotoSize + st::profileListPadding.width(), top + st::profileListNameTop, _width - _kickWidth - st::profileListPadding.width() - st::profileListPhotoSize - st::profileListPadding.width()); data->name.drawElided(p, _left + st::profileListPhotoSize + st::profileListPadding.width(), top + st::profileListNameTop, _width - _kickWidth - st::profileListPadding.width() - st::profileListPhotoSize - st::profileListPadding.width());
p.setFont(st::profileSubFont->f); p.setFont(st::profileSubFont->f);
p.setPen((App::onlineColorUse(user->onlineTill, l_time) ? st::profileOnlineColor : st::profileOfflineColor)->p); p.setPen((App::onlineColorUse(user, l_time) ? st::profileOnlineColor : st::profileOfflineColor)->p);
p.drawText(_left + st::profileListPhotoSize + st::profileListPadding.width(), top + st::profileListPadding.height() + st::profileListPhotoSize - st::profileListStatusBottom, data->online); p.drawText(_left + st::profileListPhotoSize + st::profileListPadding.width(), top + st::profileListPadding.height() + st::profileListPhotoSize - st::profileListStatusBottom, data->online);
if (data->cankick) { if (data->cankick) {
@ -906,12 +905,10 @@ void ProfileInner::onMenuDestroy(QObject *obj) {
} }
void ProfileInner::onCopyPhone() { void ProfileInner::onCopyPhone() {
DEBUG_LOG(("Setting text to clipboard from user phone: %1").arg(_phoneText));
QApplication::clipboard()->setText(_phoneText); QApplication::clipboard()->setText(_phoneText);
} }
void ProfileInner::onCopyUsername() { void ProfileInner::onCopyUsername() {
DEBUG_LOG(("Setting text to clipboard from username: @%1").arg(_peerUser->username));
QApplication::clipboard()->setText('@' + _peerUser->username); QApplication::clipboard()->setText('@' + _peerUser->username);
} }

View File

@ -258,6 +258,8 @@ void UserData::nameUpdated() {
} }
void UserData::madeAction() { void UserData::madeAction() {
if (botInfo || isServiceUser(id)) return;
int32 t = unixtime(); int32 t = unixtime();
if (onlineTill <= 0 && -onlineTill < t) { if (onlineTill <= 0 && -onlineTill < t) {
onlineTill = -t - SetOnlineAfterActivity; onlineTill = -t - SetOnlineAfterActivity;

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.29</string> <string>0.8.30</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

@ -1701,7 +1701,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.29; CURRENT_PROJECT_VERSION = 0.8.30;
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;
@ -1719,7 +1719,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.29; CURRENT_PROJECT_VERSION = 0.8.30;
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;
@ -1745,10 +1745,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.29; CURRENT_PROJECT_VERSION = 0.8.30;
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.29; DYLIB_CURRENT_VERSION = 0.8.30;
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;
@ -1888,10 +1888,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.29; CURRENT_PROJECT_VERSION = 0.8.30;
DEBUG_INFORMATION_FORMAT = dwarf; DEBUG_INFORMATION_FORMAT = dwarf;
DYLIB_COMPATIBILITY_VERSION = 0.8; DYLIB_COMPATIBILITY_VERSION = 0.8;
DYLIB_CURRENT_VERSION = 0.8.29; DYLIB_CURRENT_VERSION = 0.8.30;
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 8029 0.8.29 1 echo 8030 0.8.30 0
# AppVersion AppVersionStr DevChannel # AppVersion AppVersionStr DevChannel