mirror of
https://github.com/telegramdesktop/tdesktop
synced 2024-12-15 02:44:45 +00:00
version 0.8.27.dev ready
This commit is contained in:
parent
52ea153c31
commit
c291bf0861
@ -1,9 +1,9 @@
|
||||
@echo OFF
|
||||
|
||||
set "AppVersion=8026"
|
||||
set "AppVersionStrSmall=0.8.26"
|
||||
set "AppVersionStr=0.8.26"
|
||||
set "AppVersionStrFull=0.8.26.0"
|
||||
set "AppVersion=8027"
|
||||
set "AppVersionStrSmall=0.8.27"
|
||||
set "AppVersionStr=0.8.27"
|
||||
set "AppVersionStrFull=0.8.27.0"
|
||||
set "DevChannel=1"
|
||||
|
||||
if %DevChannel% neq 0 goto preparedev
|
||||
|
@ -1011,8 +1011,8 @@ recordSignalMin: 5px;
|
||||
recordSignalMax: 10px;
|
||||
recordCancel: #aaa;
|
||||
recordCancelActive: #ec6466;
|
||||
recordFont: font(16px);
|
||||
recordTextTop: 12px;
|
||||
recordFont: font(13px);
|
||||
recordTextTop: 14px;
|
||||
|
||||
replySkip: 51px;
|
||||
replyColor: #377aae;
|
||||
@ -1679,7 +1679,7 @@ botKbColor: #8a8a8f;
|
||||
botKbFont: font(16px);
|
||||
botKbButton: botKeyboardButton {
|
||||
margin: 10px;
|
||||
padding: 14px;
|
||||
padding: 10px;
|
||||
height: 46px;
|
||||
textTop: 13px;
|
||||
downTextTop: 14px;
|
||||
|
@ -1977,12 +1977,15 @@ namespace App {
|
||||
|
||||
void feedReplyMarkup(MsgId msgId, const MTPReplyMarkup &markup) {
|
||||
ReplyMarkup data;
|
||||
ReplyMarkup::Commands &commands(data.commands);
|
||||
switch (markup.type()) {
|
||||
case mtpc_replyKeyboardMarkup: {
|
||||
const MTPDreplyKeyboardMarkup &d(markup.c_replyKeyboardMarkup());
|
||||
data.flags = d.vflags.v;
|
||||
|
||||
const QVector<MTPKeyboardButtonRow> &v(d.vrows.c_vector().v);
|
||||
if (!v.isEmpty()) {
|
||||
data.reserve(v.size());
|
||||
commands.reserve(v.size());
|
||||
for (int32 i = 0, l = v.size(); i < l; ++i) {
|
||||
switch (v.at(i).type()) {
|
||||
case mtpc_keyboardButtonRow: {
|
||||
@ -1998,12 +2001,12 @@ namespace App {
|
||||
} break;
|
||||
}
|
||||
}
|
||||
if (!btns.isEmpty()) data.push_back(btns);
|
||||
if (!btns.isEmpty()) commands.push_back(btns);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
}
|
||||
if (!data.isEmpty()) {
|
||||
if (!commands.isEmpty()) {
|
||||
replyMarkups.insert(msgId, data);
|
||||
}
|
||||
}
|
||||
@ -2016,7 +2019,7 @@ namespace App {
|
||||
}
|
||||
|
||||
const ReplyMarkup &replyMarkup(MsgId msgId) {
|
||||
static ReplyMarkup zeroMarkup;
|
||||
static ReplyMarkup zeroMarkup(MTPDreplyKeyboardMarkup_flag_ZERO);
|
||||
ReplyMarkups::const_iterator i = replyMarkups.constFind(msgId);
|
||||
if (i == replyMarkups.cend()) return zeroMarkup;
|
||||
return i.value();
|
||||
@ -2046,15 +2049,21 @@ namespace App {
|
||||
}
|
||||
}
|
||||
|
||||
void insertBotCommand(const QString &cmd) {
|
||||
if (App::main()) {
|
||||
App::main()->insertBotCommand(cmd);
|
||||
}
|
||||
}
|
||||
|
||||
void searchByHashtag(const QString &tag) {
|
||||
if (App::main()) {
|
||||
App::main()->searchMessages(tag + ' ');
|
||||
}
|
||||
}
|
||||
|
||||
void openUserByName(const QString &username, bool toProfile, const QString &start, const QString &startToken) {
|
||||
void openUserByName(const QString &username, bool toProfile, const QString &startToken) {
|
||||
if (App::main()) {
|
||||
App::main()->openUserByName(username, toProfile, start, startToken);
|
||||
App::main()->openUserByName(username, toProfile, startToken);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,13 @@ typedef QHash<VideoData*, HistoryItemsMap> VideoItems;
|
||||
typedef QHash<AudioData*, HistoryItemsMap> AudioItems;
|
||||
typedef QHash<DocumentData*, HistoryItemsMap> DocumentItems;
|
||||
typedef QHash<WebPageData*, HistoryItemsMap> WebPageItems;
|
||||
typedef QList<QList<QString> > ReplyMarkup;
|
||||
struct ReplyMarkup {
|
||||
ReplyMarkup(int32 flags = 0) : flags(flags) {
|
||||
}
|
||||
typedef QList<QList<QString> > Commands;
|
||||
Commands commands;
|
||||
int32 flags;
|
||||
};
|
||||
|
||||
enum RoundCorners {
|
||||
MaskCorners = 0x00, // for images
|
||||
@ -234,8 +240,9 @@ namespace App {
|
||||
void setProxySettings(QTcpSocket &socket);
|
||||
|
||||
void sendBotCommand(const QString &cmd, MsgId replyTo = 0);
|
||||
void insertBotCommand(const QString &cmd);
|
||||
void searchByHashtag(const QString &tag);
|
||||
void openUserByName(const QString &username, bool toProfile = false, const QString &start = QString(), const QString &startToken = QString());
|
||||
void openUserByName(const QString &username, bool toProfile = false, const QString &startToken = QString());
|
||||
void joinGroupByHash(const QString &hash);
|
||||
void stickersBox(const QString &name);
|
||||
void openLocalUrl(const QString &url);
|
||||
|
@ -640,7 +640,7 @@ void Application::checkMapVersion() {
|
||||
psRegisterCustomScheme();
|
||||
if (Local::oldMapVersion()) {
|
||||
QString versionFeatures;
|
||||
if (DevChannel && Local::oldMapVersion() < 8026) {
|
||||
if (DevChannel && Local::oldMapVersion() < 8027) {
|
||||
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) {
|
||||
versionFeatures = lng_new_version_text(lt_blog_link, qsl("https://telegram.org/blog/bot-revolution"));// lang(lng_new_version_text).trimmed();
|
||||
|
@ -91,7 +91,15 @@ void ContactsInner::onPeerNameChanged(PeerData *peer, const PeerData::Names &old
|
||||
}
|
||||
|
||||
void ContactsInner::onAddBot() {
|
||||
App::main()->addParticipants(_addToChat, QVector<UserData*>(1, _bot));
|
||||
if (_bot->botInfo && !_bot->botInfo->startGroupToken.isEmpty()) {
|
||||
uint64 randomId = MTP::nonce<uint64>();
|
||||
MTP::send(MTPmessages_StartBot(_bot->inputUser, MTP_int(App::chatFromPeer(_addToChat->id)), MTP_long(randomId), MTP_string(_bot->botInfo->startGroupToken)), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcFail(&MainWidget::addParticipantFail, _bot));
|
||||
|
||||
App::wnd()->hideLayer();
|
||||
App::main()->showPeer(_addToChat->id, 0, false);
|
||||
} else {
|
||||
App::main()->addParticipants(_addToChat, QVector<UserData*>(1, _bot));
|
||||
}
|
||||
}
|
||||
|
||||
void ContactsInner::peerUpdated(PeerData *peer) {
|
||||
@ -738,7 +746,10 @@ ContactsInner::~ContactsInner() {
|
||||
for (ContactsData::iterator i = _contactsData.begin(), e = _contactsData.end(); i != e; ++i) {
|
||||
delete *i;
|
||||
}
|
||||
if (_bot) delete _contacts;
|
||||
if (_bot) {
|
||||
delete _contacts;
|
||||
if (_bot->botInfo) _bot->botInfo->startGroupToken = QString();
|
||||
}
|
||||
}
|
||||
|
||||
void ContactsInner::resizeEvent(QResizeEvent *e) {
|
||||
|
@ -17,8 +17,8 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
static const int32 AppVersion = 8026;
|
||||
static const wchar_t *AppVersionStr = L"0.8.26";
|
||||
static const int32 AppVersion = 8027;
|
||||
static const wchar_t *AppVersionStr = L"0.8.27";
|
||||
static const bool DevChannel = true;
|
||||
|
||||
static const wchar_t *AppNameOld = L"Telegram Win (Unofficial)";
|
||||
|
@ -2411,7 +2411,7 @@ void MentionsInner::paintEvent(QPaintEvent *e) {
|
||||
|
||||
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 htagleft = st::btnAttachPhoto.width + st::taMsgField.textMrg.left() - st::dlgShadow, htagwidth = width() - st::mentionPadding.right() - htagleft;
|
||||
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 last = _rows->isEmpty() ? (_hrows->isEmpty() ? _crows->size() : _hrows->size()) : _rows->size();
|
||||
|
@ -30,7 +30,7 @@ namespace {
|
||||
const QRegularExpression _reMailStart(qsl("^[a-zA-Z\\-_\\.0-9]{1,256}\\@"));
|
||||
const QRegularExpression _reHashtag(qsl("(^|[\\s\\.,:;<>|'\"\\[\\]\\{\\}`\\~\\!\\%\\^\\*\\(\\)\\-\\+=\\x10])#[\\w]{2,64}([\\W]|$)"), QRegularExpression::UseUnicodePropertiesOption);
|
||||
const QRegularExpression _reMention(qsl("(^|[\\s\\.,:;<>|'\"\\[\\]\\{\\}`\\~\\!\\%\\^\\*\\(\\)\\-\\+=\\x10])@[A-Za-z_0-9]{5,32}([\\W]|$)"), QRegularExpression::UseUnicodePropertiesOption);
|
||||
const QRegularExpression _reBotCommand(qsl("(^|[\\s\\.,:;<>|'\"\\[\\]\\{\\}`\\~\\!\\%\\^\\*\\(\\)\\-\\+=\\x10])/[\\w]{1,64}(@[A-Za-z_0-9]{5,32})?([\\W]|$)"), QRegularExpression::UseUnicodePropertiesOption);
|
||||
const QRegularExpression _reBotCommand(qsl("(^|[\\s\\.,:;<>|'\"\\[\\]\\{\\}`\\~\\!\\%\\^\\*\\(\\)\\-\\+=\\x10])/[A-Za-z_0-9]{1,64}(@[A-Za-z_0-9]{5,32})?([\\W]|$)"));
|
||||
QSet<int32> _validProtocols, _validTopDomains;
|
||||
|
||||
const style::textStyle *_textStyle = 0;
|
||||
@ -757,7 +757,7 @@ void TextLink::onClick(Qt::MouseButton button) const {
|
||||
start = (start == qsl("sg") ? qsl("startgroup") : (start == qsl("s") ? qsl("start") : QString()));
|
||||
}
|
||||
}
|
||||
App::openUserByName(telegramMeUser.captured(1), start == qsl("startgroup"), start, startToken);
|
||||
App::openUserByName(telegramMeUser.captured(1), start == qsl("startgroup"), startToken);
|
||||
} else if (telegramMeGroup.hasMatch()) {
|
||||
App::joinGroupByHash(telegramMeGroup.captured(1));
|
||||
} else if (telegramMeStickers.hasMatch()) {
|
||||
@ -784,7 +784,8 @@ void HashtagLink::onClick(Qt::MouseButton button) const {
|
||||
|
||||
void BotCommandLink::onClick(Qt::MouseButton button) const {
|
||||
if (button == Qt::LeftButton || button == Qt::MiddleButton) {
|
||||
App::sendBotCommand(_cmd);
|
||||
App::insertBotCommand(_cmd);
|
||||
// App::sendBotCommand(_cmd);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -310,6 +310,8 @@ History::History(const PeerId &peerId) : width(0), height(0)
|
||||
, lastWidth(0)
|
||||
, lastScrollTop(History::ScrollMax)
|
||||
, mute(isNotifyMuted(peer->notify))
|
||||
, lastKeyboardInited(false)
|
||||
, lastKeyboardUsed(false)
|
||||
, lastKeyboardId(0)
|
||||
, lastKeyboardFrom(0)
|
||||
, sendRequestId(0)
|
||||
@ -814,11 +816,21 @@ HistoryItem *History::doAddToBack(HistoryBlock *to, bool newBlock, HistoryItem *
|
||||
}
|
||||
}
|
||||
if (adding->hasReplyMarkup()) {
|
||||
lastKeyboardId = adding->id;
|
||||
lastKeyboardFrom = adding->from()->id;
|
||||
} else if (lastKeyboardFrom == adding->from()->id) {
|
||||
lastKeyboardId = 0;
|
||||
lastKeyboardFrom = 0;
|
||||
if (peer->chat) {
|
||||
peer->asChat()->markupSenders.insert(adding->from(), true);
|
||||
}
|
||||
if (App::replyMarkup(adding->id).flags & MTPDreplyKeyboardMarkup_flag_ZERO) { // zero markup means replyKeyboardHide
|
||||
if (lastKeyboardFrom == adding->from()->id || (!lastKeyboardInited && !peer->chat && !adding->out())) {
|
||||
lastKeyboardInited = true;
|
||||
lastKeyboardId = 0;
|
||||
lastKeyboardFrom = 0;
|
||||
}
|
||||
} else {
|
||||
lastKeyboardInited = true;
|
||||
lastKeyboardId = adding->id;
|
||||
lastKeyboardFrom = adding->from()->id;
|
||||
lastKeyboardUsed = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return adding;
|
||||
@ -923,12 +935,40 @@ void History::addToFront(const QVector<MTPMessage> &slice) {
|
||||
}
|
||||
}
|
||||
if (item->from()->id) {
|
||||
if (lastAuthors && !lastAuthors->contains(item->from())) {
|
||||
if (item->hasReplyMarkup() && !lastKeyboardId) {
|
||||
if (lastAuthors) { // chats
|
||||
if (!lastAuthors->contains(item->from())) {
|
||||
lastAuthors->push_back(item->from());
|
||||
}
|
||||
if (!lastKeyboardInited && item->hasReplyMarkup() && !item->out()) { // chats with bots
|
||||
bool wasKeyboardHide = peer->asChat()->markupSenders.contains(item->from());
|
||||
if (!wasKeyboardHide) {
|
||||
peer->asChat()->markupSenders.insert(item->from(), true);
|
||||
}
|
||||
if (!(App::replyMarkup(item->id).flags & MTPDreplyKeyboardMarkup_flag_ZERO)) {
|
||||
if (!lastKeyboardInited) {
|
||||
lastKeyboardInited = true;
|
||||
if (wasKeyboardHide) {
|
||||
lastKeyboardId = 0;
|
||||
lastKeyboardFrom = 0;
|
||||
} else {
|
||||
lastKeyboardId = item->id;
|
||||
lastKeyboardFrom = item->from()->id;
|
||||
lastKeyboardUsed = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (!lastKeyboardInited && item->hasReplyMarkup() && !item->out()) { // conversations with bots
|
||||
lastKeyboardInited = true;
|
||||
if (App::replyMarkup(item->id).flags & MTPDreplyKeyboardMarkup_flag_ZERO) {
|
||||
lastKeyboardId = 0;
|
||||
lastKeyboardFrom = 0;
|
||||
} else {
|
||||
lastKeyboardInited = true;
|
||||
lastKeyboardId = item->id;
|
||||
lastKeyboardFrom = item->from()->id;
|
||||
lastKeyboardUsed = false;
|
||||
}
|
||||
lastAuthors->push_back(item->from());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1286,13 +1326,19 @@ void History::clear(bool leaveItems) {
|
||||
}
|
||||
Parent::clear();
|
||||
setMsgCount(0);
|
||||
if (!leaveItems) {
|
||||
if (leaveItems) {
|
||||
lastKeyboardInited = false;
|
||||
} else {
|
||||
setUnreadCount(0);
|
||||
lastMsg = 0;
|
||||
}
|
||||
height = 0;
|
||||
oldLoaded = false;
|
||||
if (peer->chat) peer->asChat()->lastAuthors.clear();
|
||||
if (peer->chat) {
|
||||
peer->asChat()->lastAuthors.clear();
|
||||
peer->asChat()->markupSenders.clear();
|
||||
}
|
||||
if (leaveItems && App::main()) App::main()->historyCleared(this);
|
||||
}
|
||||
|
||||
History::Parent::iterator History::erase(History::Parent::iterator i) {
|
||||
|
@ -251,6 +251,7 @@ struct History : public QList<HistoryBlock*> {
|
||||
int32 lastWidth, lastScrollTop;
|
||||
bool mute;
|
||||
|
||||
bool lastKeyboardInited, lastKeyboardUsed;
|
||||
MsgId lastKeyboardId;
|
||||
PeerId lastKeyboardFrom;
|
||||
|
||||
|
@ -928,7 +928,7 @@ QString HistoryList::getSelectedText() const {
|
||||
|
||||
void HistoryList::keyPressEvent(QKeyEvent *e) {
|
||||
if (e->key() == Qt::Key_Escape) {
|
||||
historyWidget->onClearSelected();
|
||||
historyWidget->onListEscapePressed();
|
||||
} else if (e == QKeySequence::Copy && !_selected.isEmpty()) {
|
||||
copySelectedText();
|
||||
} else if (e == QKeySequence::Delete) {
|
||||
@ -1188,6 +1188,9 @@ void HistoryList::onUpdateSelected() {
|
||||
App::hoveredItem(0);
|
||||
}
|
||||
}
|
||||
if (_dragItem && _dragItem->detached()) {
|
||||
dragActionCancel();
|
||||
}
|
||||
linkTipTimer.start(1000);
|
||||
|
||||
Qt::CursorShape cur = style::cur_default;
|
||||
@ -1446,9 +1449,10 @@ void MessageField::focusInEvent(QFocusEvent *e) {
|
||||
emit focused();
|
||||
}
|
||||
|
||||
BotKeyboard::BotKeyboard() : _wasForMsgId(0),
|
||||
BotKeyboard::BotKeyboard() : _wasForMsgId(0), _height(0), _maxOuterHeight(0), _maximizeSize(false), _singleUse(false),
|
||||
_sel(-1), _down(-1), _hoverAnim(animFunc(this, &BotKeyboard::hoverStep)), _st(&st::botKbButton) {
|
||||
setGeometry(0, 0, _st->margin, _st->margin);
|
||||
_height = _st->margin;
|
||||
setMouseTracking(true);
|
||||
|
||||
_cmdTipTimer.setSingleShot(true);
|
||||
@ -1474,9 +1478,17 @@ void BotKeyboard::paintEvent(QPaintEvent *e) {
|
||||
|
||||
if (rtl()) rect.moveLeft(width() - rect.left() - rect.width());
|
||||
|
||||
int32 tx = rect.x(), tw = rect.width();
|
||||
if (tw > st::botKbFont->elidew + _st->padding * 2) {
|
||||
tx += _st->padding;
|
||||
tw -= _st->padding * 2;
|
||||
} else if (tw > st::botKbFont->elidew) {
|
||||
tx += (tw - st::botKbFont->elidew) / 2;
|
||||
tw = st::botKbFont->elidew;
|
||||
}
|
||||
if (_down == i * MatrixRowShift + j) {
|
||||
App::roundRect(p, rect, st::botKbDownBg, BotKeyboardDownCorners);
|
||||
btn.text.drawElided(p, rect.x(), rect.y() + _st->downTextTop, rect.width(), 1, style::al_top);
|
||||
btn.text.drawElided(p, tx, rect.y() + _st->downTextTop + ((rect.height() - _st->height) / 2), tw, 1, style::al_top);
|
||||
} else {
|
||||
App::roundRect(p, rect, st::botKbBg, BotKeyboardCorners);
|
||||
float64 hover = btn.hover;
|
||||
@ -1485,7 +1497,7 @@ void BotKeyboard::paintEvent(QPaintEvent *e) {
|
||||
App::roundRect(p, rect, st::botKbOverBg, BotKeyboardOverCorners);
|
||||
p.setOpacity(1);
|
||||
}
|
||||
btn.text.drawElided(p, rect.x(), rect.y() + _st->textTop, rect.width(), 1, style::al_top);
|
||||
btn.text.drawElided(p, tx, rect.y() + _st->textTop + ((rect.height() - _st->height) / 2), tw, 1, style::al_top);
|
||||
}
|
||||
}
|
||||
if (j < s) break;
|
||||
@ -1494,13 +1506,15 @@ void BotKeyboard::paintEvent(QPaintEvent *e) {
|
||||
|
||||
void BotKeyboard::resizeEvent(QResizeEvent *e) {
|
||||
updateStyle();
|
||||
int32 h = (_btns.size() + 1) * _st->margin + _btns.size() * _st->height;
|
||||
if (height() != h) {
|
||||
resize(width(), h);
|
||||
|
||||
_height = (_btns.size() + 1) * _st->margin + _btns.size() * _st->height;
|
||||
if (_maximizeSize) _height = qMax(_height, _maxOuterHeight);
|
||||
if (height() != _height) {
|
||||
resize(width(), _height);
|
||||
return;
|
||||
}
|
||||
|
||||
int32 y = _st->margin;
|
||||
float64 y = _st->margin, btnh = _btns.isEmpty() ? _st->height : (float64(_height - _st->margin) / _btns.size());
|
||||
for (int32 i = 0, l = _btns.size(); i != l; ++i) {
|
||||
int32 j = 0, s = _btns.at(i).size();
|
||||
|
||||
@ -1516,15 +1530,15 @@ void BotKeyboard::resizeEvent(QResizeEvent *e) {
|
||||
float64 x = _st->margin, coef = widthForText / widthOfText;
|
||||
for (j = 0; j != s; ++j) {
|
||||
Button &btn(_btns[i][j]);
|
||||
float64 tw = widthForText / float64(s)/*qMax(btn.text.maxWidth(), 1) * coef*/, w = 2 * _st->padding + tw;
|
||||
float64 tw = widthForText / float64(s), w = 2 * _st->padding + tw;
|
||||
if (w < _st->padding) w = _st->padding;
|
||||
|
||||
btn.rect = QRect(qRound(x), y, qRound(w), _st->height);
|
||||
btn.rect = QRect(qRound(x), qRound(y), qRound(w), qRound(btnh - _st->margin));
|
||||
x += w + _st->margin;
|
||||
|
||||
btn.full = tw >= btn.text.maxWidth();
|
||||
}
|
||||
y += _st->height + _st->margin;
|
||||
y += btnh;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1565,11 +1579,15 @@ bool BotKeyboard::updateMarkup(HistoryItem *to) {
|
||||
clearSelection();
|
||||
_btns.clear();
|
||||
const ReplyMarkup &markup(App::replyMarkup(to->id));
|
||||
if (!markup.isEmpty()) {
|
||||
int32 i = 0, l = qMin(markup.size(), 32);
|
||||
_maximizeSize = !(markup.flags & MTPDreplyKeyboardMarkup_flag_resize);
|
||||
_singleUse = markup.flags & MTPDreplyKeyboardMarkup_flag_single_use;
|
||||
|
||||
const ReplyMarkup::Commands &commands(markup.commands);
|
||||
if (!commands.isEmpty()) {
|
||||
int32 i = 0, l = qMin(commands.size(), 32);
|
||||
_btns.reserve(l);
|
||||
for (; i != l; ++i) {
|
||||
const QList<QString> &row(markup.at(i));
|
||||
const QList<QString> &row(commands.at(i));
|
||||
QList<Button> btns;
|
||||
int32 j = 0, s = qMin(row.size(), 16);
|
||||
btns.reserve(s);
|
||||
@ -1580,9 +1598,10 @@ bool BotKeyboard::updateMarkup(HistoryItem *to) {
|
||||
}
|
||||
|
||||
updateStyle();
|
||||
int32 h = (_btns.size() + 1) * _st->margin + _btns.size() * _st->height;
|
||||
if (height() != h) {
|
||||
resize(width(), h);
|
||||
_height = (_btns.size() + 1) * _st->margin + _btns.size() * _st->height;
|
||||
if (_maximizeSize) _height = qMax(_height, _maxOuterHeight);
|
||||
if (height() != _height) {
|
||||
resize(width(), _height);
|
||||
} else {
|
||||
resizeEvent(0);
|
||||
}
|
||||
@ -1590,6 +1609,7 @@ bool BotKeyboard::updateMarkup(HistoryItem *to) {
|
||||
return true;
|
||||
}
|
||||
if (_wasForMsgId) {
|
||||
_maximizeSize = _singleUse = false;
|
||||
_wasForMsgId = 0;
|
||||
clearSelection();
|
||||
_btns.clear();
|
||||
@ -1619,15 +1639,26 @@ bool BotKeyboard::hoverStep(float64 ms) {
|
||||
return !_animations.isEmpty();
|
||||
}
|
||||
|
||||
void BotKeyboard::resizeToWidth(int32 width) {
|
||||
void BotKeyboard::resizeToWidth(int32 width, int32 maxOuterHeight) {
|
||||
updateStyle(width);
|
||||
resize(width, (_btns.size() + 1) * _st->margin + _btns.size() * _st->height);
|
||||
_height = (_btns.size() + 1) * _st->margin + _btns.size() * _st->height;
|
||||
_maxOuterHeight = maxOuterHeight;
|
||||
|
||||
if (_maximizeSize) _height = qMax(_height, _maxOuterHeight);
|
||||
resize(width, _height);
|
||||
}
|
||||
|
||||
bool BotKeyboard::maximizeSize() const {
|
||||
return _maximizeSize;
|
||||
}
|
||||
|
||||
bool BotKeyboard::singleUse() const {
|
||||
return _singleUse;
|
||||
}
|
||||
|
||||
void BotKeyboard::updateStyle(int32 w) {
|
||||
if (w < 0) w = width();
|
||||
_st = &st::botKbButton;
|
||||
bool tiny = false;
|
||||
for (int32 i = 0, l = _btns.size(); i != l; ++i) {
|
||||
int32 j = 0, s = _btns.at(i).size();
|
||||
int32 widthLeft = w - (s * _st->margin + st::botKbScroll.width + s * 2 * _st->padding);
|
||||
@ -1637,7 +1668,7 @@ void BotKeyboard::updateStyle(int32 w) {
|
||||
widthLeft -= qMax(btn.text.maxWidth(), 1);
|
||||
if (widthLeft < 0) break;
|
||||
}
|
||||
if (j != s) {
|
||||
if (j != s && s > 3) {
|
||||
_st = &st::botKbTinyButton;
|
||||
break;
|
||||
}
|
||||
@ -1992,6 +2023,7 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent)
|
||||
, _toHistoryEnd(this, st::historyToEnd)
|
||||
, _attachMention(this)
|
||||
, _send(this, lang(lng_send_button), st::btnSend)
|
||||
, _botStart(this, lang(lng_bot_start), st::btnSend)
|
||||
, _attachDocument(this, st::btnAttachDocument)
|
||||
, _attachPhoto(this, st::btnAttachPhoto)
|
||||
, _attachEmoji(this, st::btnAttachEmoji)
|
||||
@ -2034,6 +2066,7 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent)
|
||||
connect(&_toHistoryEnd, SIGNAL(clicked()), this, SLOT(onHistoryToEnd()));
|
||||
connect(&_replyForwardPreviewCancel, SIGNAL(clicked()), this, SLOT(onReplyForwardPreviewCancel()));
|
||||
connect(&_send, SIGNAL(clicked()), this, SLOT(onSend()));
|
||||
connect(&_botStart, SIGNAL(clicked()), this, SLOT(onBotStart()));
|
||||
connect(&_attachDocument, SIGNAL(clicked()), this, SLOT(onDocumentSelect()));
|
||||
connect(&_attachPhoto, SIGNAL(clicked()), this, SLOT(onPhotoSelect()));
|
||||
connect(&_field, SIGNAL(submitted(bool)), this, SLOT(onSend(bool)));
|
||||
@ -2093,6 +2126,7 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent)
|
||||
_field.hide();
|
||||
_field.resize(width() - _send.width() - _attachDocument.width() - _attachEmoji.width(), _send.height() - 2 * st::sendPadding);
|
||||
_send.hide();
|
||||
_botStart.hide();
|
||||
|
||||
_attachDocument.hide();
|
||||
_attachPhoto.hide();
|
||||
@ -2229,7 +2263,7 @@ void HistoryWidget::activate() {
|
||||
}
|
||||
}
|
||||
if (_list) {
|
||||
if (_selCount || _recording) {
|
||||
if (_selCount || _recording || !_botStart.isHidden()) {
|
||||
_list->setFocus();
|
||||
} else {
|
||||
_field.setFocus();
|
||||
@ -2606,6 +2640,11 @@ void HistoryWidget::showPeer(const PeerId &peer, MsgId msgId, bool force, bool l
|
||||
_list = 0;
|
||||
updateTopBarSelection();
|
||||
|
||||
if (_activeHist && _activeHist->peer->id != peer && (!leaveActive || _activeHist != hist)) {
|
||||
if (!_activeHist->peer->chat && _activeHist->peer->asUser()->botInfo) {
|
||||
_activeHist->peer->asUser()->botInfo->startToken = QString();
|
||||
}
|
||||
}
|
||||
if (leaveActive && hist) {
|
||||
_activeHist = hist;
|
||||
} else {
|
||||
@ -2614,6 +2653,9 @@ void HistoryWidget::showPeer(const PeerId &peer, MsgId msgId, bool force, bool l
|
||||
}
|
||||
if (hist) {
|
||||
App::main()->dlgUpdated(hist);
|
||||
if (!hist->peer->chat && hist->peer->asUser()->botInfo) {
|
||||
hist->peer->asUser()->botInfo->startToken = QString();
|
||||
}
|
||||
}
|
||||
}
|
||||
histPeer = peer ? App::peer(peer) : 0;
|
||||
@ -2743,6 +2785,7 @@ void HistoryWidget::updateControlsVisibility() {
|
||||
_scroll.hide();
|
||||
_kbScroll.hide();
|
||||
_send.hide();
|
||||
_botStart.hide();
|
||||
_toHistoryEnd.hide();
|
||||
_attachMention.hide();
|
||||
_field.hide();
|
||||
@ -2765,66 +2808,85 @@ void HistoryWidget::updateControlsVisibility() {
|
||||
}
|
||||
if (!histPeer->chat || !histPeer->asChat()->forbidden) {
|
||||
checkMentionDropdown();
|
||||
if (cHasAudioCapture() && _field.getLastText().isEmpty() && !App::main()->hasForwardingItems()) {
|
||||
bool botStart = !histPeer->chat && histPeer->asUser()->botInfo && (!histPeer->asUser()->botInfo->startToken.isEmpty() || hist->isEmpty() && !hist->lastMsg);
|
||||
if (botStart) {
|
||||
if (_botStart.isHidden()) {
|
||||
_botStart.clearState();
|
||||
_botStart.show();
|
||||
}
|
||||
_send.hide();
|
||||
setMouseTracking(true);
|
||||
mouseMoveEvent(0);
|
||||
} else {
|
||||
_send.show();
|
||||
setMouseTracking(false);
|
||||
_recordAnim.stop();
|
||||
_inRecord = _inField = false;
|
||||
a_recordOver = anim::fvalue(0, 0);
|
||||
}
|
||||
if (_recording) {
|
||||
_field.hide();
|
||||
_attachEmoji.hide();
|
||||
_kbShow.hide();
|
||||
_kbHide.hide();
|
||||
_attachDocument.hide();
|
||||
_attachPhoto.hide();
|
||||
if (_kbShown) {
|
||||
_kbScroll.show();
|
||||
} else {
|
||||
_kbScroll.hide();
|
||||
}
|
||||
_kbScroll.hide();
|
||||
_replyForwardPreviewCancel.hide();
|
||||
} else {
|
||||
_field.show();
|
||||
if (_kbShown) {
|
||||
_kbScroll.show();
|
||||
_attachEmoji.hide();
|
||||
_kbHide.show();
|
||||
_kbShow.hide();
|
||||
_botStart.hide();
|
||||
if (cHasAudioCapture() && _field.getLastText().isEmpty() && !App::main()->hasForwardingItems()) {
|
||||
_send.hide();
|
||||
setMouseTracking(true);
|
||||
mouseMoveEvent(0);
|
||||
} else {
|
||||
_kbScroll.hide();
|
||||
_attachEmoji.show();
|
||||
_send.show();
|
||||
setMouseTracking(false);
|
||||
_recordAnim.stop();
|
||||
_inRecord = _inField = false;
|
||||
a_recordOver = anim::fvalue(0, 0);
|
||||
}
|
||||
if (_recording) {
|
||||
_field.hide();
|
||||
_attachEmoji.hide();
|
||||
_kbShow.hide();
|
||||
_kbHide.hide();
|
||||
if (_keyboard.hasMarkup()) {
|
||||
_kbShow.show();
|
||||
_attachDocument.hide();
|
||||
_attachPhoto.hide();
|
||||
if (_kbShown) {
|
||||
_kbScroll.show();
|
||||
} else {
|
||||
_kbScroll.hide();
|
||||
}
|
||||
} else {
|
||||
_field.show();
|
||||
if (_kbShown) {
|
||||
_kbScroll.show();
|
||||
_attachEmoji.hide();
|
||||
_kbHide.show();
|
||||
_kbShow.hide();
|
||||
} else {
|
||||
_kbScroll.hide();
|
||||
_attachEmoji.show();
|
||||
_kbHide.hide();
|
||||
if (_keyboard.hasMarkup()) {
|
||||
_kbShow.show();
|
||||
} else {
|
||||
_kbShow.hide();
|
||||
}
|
||||
}
|
||||
if (cDefaultAttach() == dbidaPhoto) {
|
||||
_attachDocument.hide();
|
||||
_attachPhoto.show();
|
||||
} else {
|
||||
_attachDocument.show();
|
||||
_attachPhoto.hide();
|
||||
}
|
||||
}
|
||||
if (cDefaultAttach() == dbidaPhoto) {
|
||||
_attachDocument.hide();
|
||||
_attachPhoto.show();
|
||||
if ((_replyToId || App::main()->hasForwardingItems() || (_previewData && _previewData->pendingTill >= 0))) {
|
||||
if (_replyForwardPreviewCancel.isHidden()) {
|
||||
_replyForwardPreviewCancel.show();
|
||||
resizeEvent(0);
|
||||
update();
|
||||
}
|
||||
} else {
|
||||
_attachDocument.show();
|
||||
_attachPhoto.hide();
|
||||
_replyForwardPreviewCancel.hide();
|
||||
}
|
||||
}
|
||||
if ((_replyToId || App::main()->hasForwardingItems() || (_previewData && _previewData->pendingTill >= 0))) {
|
||||
if (_replyForwardPreviewCancel.isHidden()) {
|
||||
_replyForwardPreviewCancel.show();
|
||||
resizeEvent(0);
|
||||
update();
|
||||
}
|
||||
} else {
|
||||
_replyForwardPreviewCancel.hide();
|
||||
}
|
||||
} else {
|
||||
_attachMention.hide();
|
||||
_send.hide();
|
||||
_botStart.hide();
|
||||
_attachDocument.hide();
|
||||
_attachPhoto.hide();
|
||||
_attachEmoji.hide();
|
||||
@ -2849,6 +2911,7 @@ void HistoryWidget::updateControlsVisibility() {
|
||||
_kbScroll.hide();
|
||||
_attachMention.hide();
|
||||
_send.hide();
|
||||
_botStart.hide();
|
||||
_attachDocument.hide();
|
||||
_attachPhoto.hide();
|
||||
_attachEmoji.hide();
|
||||
@ -2902,6 +2965,12 @@ void HistoryWidget::historyWasRead(bool force) {
|
||||
App::main()->readServerHistory(hist, force);
|
||||
}
|
||||
|
||||
void HistoryWidget::historyCleared(History *history) {
|
||||
if (history == hist) {
|
||||
_list->dragActionCancel();
|
||||
}
|
||||
}
|
||||
|
||||
bool HistoryWidget::messagesFailed(const RPCError &error, mtpRequestId requestId) {
|
||||
if (error.type().startsWith(qsl("FLOOD_WAIT_"))) return false;
|
||||
|
||||
@ -3214,6 +3283,22 @@ void HistoryWidget::onSend(bool ctrlShiftEnter, MsgId replyTo) {
|
||||
_field.setFocus();
|
||||
}
|
||||
|
||||
void HistoryWidget::onBotStart() {
|
||||
if (histPeer->chat || !histPeer->asUser()->botInfo) {
|
||||
updateControlsVisibility();
|
||||
return;
|
||||
}
|
||||
QString token = histPeer->asUser()->botInfo->startToken;
|
||||
if (token.isEmpty()) {
|
||||
sendBotCommand(qsl("/start"), 0);
|
||||
} else {
|
||||
uint64 randomId = MTP::nonce<uint64>();
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
void HistoryWidget::onShareContact(const PeerId &peer, UserData *contact) {
|
||||
if (!contact || contact->phone.isEmpty()) return;
|
||||
|
||||
@ -3295,6 +3380,7 @@ void HistoryWidget::animShow(const QPixmap &bgAnimCache, const QPixmap &bgAnimTo
|
||||
_field.hide();
|
||||
_replyForwardPreviewCancel.hide();
|
||||
_send.hide();
|
||||
_botStart.hide();
|
||||
a_coord = back ? anim::ivalue(-st::introSlideShift, 0) : anim::ivalue(st::introSlideShift, 0);
|
||||
a_alpha = anim::fvalue(0, 1);
|
||||
a_bgCoord = back ? anim::ivalue(0, st::introSlideShift) : anim::ivalue(0, -st::introSlideShift);
|
||||
@ -3350,7 +3436,7 @@ void HistoryWidget::animStop() {
|
||||
bool HistoryWidget::recordStep(float64 ms) {
|
||||
float64 dt = ms / st::btnSend.duration;
|
||||
bool res = true;
|
||||
if (dt >= 1 || !_send.isHidden()) {
|
||||
if (dt >= 1 || !_send.isHidden() || !_botStart.isHidden()) {
|
||||
res = false;
|
||||
a_recordOver.finish();
|
||||
a_recordDown.finish();
|
||||
@ -3532,7 +3618,38 @@ void HistoryWidget::sendBotCommand(const QString &cmd, MsgId replyTo) { // reply
|
||||
|
||||
int32 botStatus = histPeer->chat ? histPeer->asChat()->botStatus : -1;
|
||||
App::main()->sendPreparedText(hist, cmd, replyTo ? ((histPeer->chat && (botStatus == 0 || botStatus == 2)) ? replyTo : -1) : 0);
|
||||
if (replyTo) cancelReply();
|
||||
if (replyTo) {
|
||||
cancelReply();
|
||||
if (_keyboard.hasMarkup() && _keyboard.singleUse() && _keyboard.forMsgId() == replyTo) {
|
||||
if (_kbShown) onKbToggle(false);
|
||||
hist->lastKeyboardUsed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HistoryWidget::insertBotCommand(const QString &cmd) {
|
||||
if (!hist) return;
|
||||
|
||||
QString toInsert = cmd;
|
||||
UserData *bot = histPeer->chat ? (App::hoveredLinkItem() ? (App::hoveredLinkItem()->toHistoryForwarded() ? App::hoveredLinkItem()->toHistoryForwarded()->fromForwarded() : App::hoveredLinkItem()->from()) : 0) : histPeer->asUser();
|
||||
QString username = (bot && bot->botInfo) ? bot->username : QString();
|
||||
if (cmd.indexOf('@') < 2 && !username.isEmpty()) {
|
||||
toInsert += '@' + username;
|
||||
}
|
||||
toInsert += ' ';
|
||||
|
||||
QString text = _field.getLastText();
|
||||
QRegularExpressionMatch m = QRegularExpression(qsl("^/[A-Za-z_0-9]{0,64}(@[A-Za-z_0-9]{0,32})?(\\s|$)")).match(text);
|
||||
if (m.hasMatch()) {
|
||||
text = toInsert + text.mid(m.capturedLength());
|
||||
} else {
|
||||
text = toInsert + text;
|
||||
}
|
||||
_field.setText(text);
|
||||
|
||||
QTextCursor cur(_field.textCursor());
|
||||
cur.movePosition(QTextCursor::End);
|
||||
_field.setTextCursor(cur);
|
||||
}
|
||||
|
||||
DragState HistoryWidget::getDragState(const QMimeData *d) {
|
||||
@ -3621,22 +3738,25 @@ void HistoryWidget::onDocumentDrop(QDropEvent *e) {
|
||||
uploadMedias(files, ToPrepareDocument);
|
||||
}
|
||||
|
||||
void HistoryWidget::onKbToggle() {
|
||||
void HistoryWidget::onKbToggle(bool manual) {
|
||||
if (_kbShown) {
|
||||
_kbHide.hide();
|
||||
_kbShow.show();
|
||||
_kbScroll.hide();
|
||||
_kbShown = false;
|
||||
_kbReplyTo = 0;
|
||||
_kbWasHidden = true;
|
||||
if (manual) _kbWasHidden = true;
|
||||
} else {
|
||||
_kbHide.show();
|
||||
_kbShow.hide();
|
||||
_kbScroll.show();
|
||||
_kbShown = true;
|
||||
_kbReplyTo = hist->peer->chat ? App::histItemById(_keyboard.forMsgId()) : 0;
|
||||
if (_kbReplyTo && !_replyToId) _replyToText.setText(st::msgFont, _kbReplyTo->inDialogsText(), _textDlgOptions);
|
||||
_kbWasHidden = false;
|
||||
if (_kbReplyTo && !_replyToId) {
|
||||
updateReplyToName();
|
||||
_replyToText.setText(st::msgFont, _kbReplyTo->inDialogsText(), _textDlgOptions);
|
||||
}
|
||||
if (manual) _kbWasHidden = false;
|
||||
}
|
||||
resizeEvent(0);
|
||||
if (_kbHide.isHidden()) {
|
||||
@ -3801,9 +3921,12 @@ void HistoryWidget::updateOnlineDisplayTimer() {
|
||||
}
|
||||
|
||||
void HistoryWidget::onFieldResize() {
|
||||
int32 maxKeyboardHeight = int(st::maxFieldHeight) - _field.height();
|
||||
_keyboard.resizeToWidth(width(), maxKeyboardHeight);
|
||||
|
||||
int32 kbh = 0;
|
||||
if (_kbShown) {
|
||||
kbh = qMin(_keyboard.height(), int(st::maxFieldHeight) - _field.height());
|
||||
kbh = qMin(_keyboard.height(), maxKeyboardHeight);
|
||||
_kbScroll.setGeometry(0, height() - kbh, width(), kbh);
|
||||
}
|
||||
_field.move(_attachDocument.x() + _attachDocument.width(), height() - kbh - _field.height() - st::sendPadding);
|
||||
@ -3811,6 +3934,7 @@ void HistoryWidget::onFieldResize() {
|
||||
|
||||
_attachDocument.move(0, height() - kbh - _attachDocument.height());
|
||||
_attachPhoto.move(_attachDocument.x(), _attachDocument.y());
|
||||
_botStart.setGeometry(0, _attachDocument.y(), width(), _botStart.height());
|
||||
_send.move(width() - _send.width(), _attachDocument.y());
|
||||
_attachEmoji.move(_send.x() - _attachEmoji.width(), height() - kbh - _attachEmoji.height());
|
||||
_kbShow.move(_attachEmoji.x() - _kbShow.width(), height() - kbh - _kbShow.height());
|
||||
@ -4160,11 +4284,12 @@ void HistoryWidget::msgUpdated(PeerId peer, const HistoryItem *msg) {
|
||||
}
|
||||
|
||||
void HistoryWidget::resizeEvent(QResizeEvent *e) {
|
||||
_keyboard.resizeToWidth(width());
|
||||
int32 maxKeyboardHeight = int(st::maxFieldHeight) - _field.height();
|
||||
_keyboard.resizeToWidth(width(), maxKeyboardHeight);
|
||||
|
||||
int32 kbh = 0;
|
||||
if (_kbShown) {
|
||||
kbh = qMin(_keyboard.height(), int(st::maxFieldHeight) - _field.height());
|
||||
kbh = qMin(_keyboard.height(), maxKeyboardHeight);
|
||||
_kbScroll.setGeometry(0, height() - kbh, width(), kbh);
|
||||
}
|
||||
_field.move(_attachDocument.x() + _attachDocument.width(), height() - kbh - _field.height() - st::sendPadding);
|
||||
@ -4180,6 +4305,7 @@ void HistoryWidget::resizeEvent(QResizeEvent *e) {
|
||||
_toHistoryEnd.move((width() - _toHistoryEnd.width()) / 2, _scroll.y() + _scroll.height() - _toHistoryEnd.height() - st::historyToEndSkip);
|
||||
|
||||
_send.move(width() - _send.width(), _attachDocument.y());
|
||||
_botStart.setGeometry(0, _attachDocument.y(), width(), _botStart.height());
|
||||
_attachEmoji.move(_send.x() - _attachEmoji.width(), height() - kbh - _attachEmoji.height());
|
||||
_kbShow.move(_attachEmoji.x() - _kbShow.width(), height() - kbh - _kbShow.height());
|
||||
_kbHide.move(_attachEmoji.x(), _attachEmoji.y());
|
||||
@ -4248,12 +4374,19 @@ void HistoryWidget::updateListSize(int32 addToY, bool initial, bool loadedDown,
|
||||
return; // scrollTopMax etc are not working after recountHeight()
|
||||
}
|
||||
|
||||
int32 newScrollHeight = height() - (hist->readyForWork() && (!histPeer->chat || !histPeer->asChat()->forbidden) ? (_field.height() + 2 * st::sendPadding) : 0);
|
||||
if (_replyToId || _kbReplyTo || App::main()->hasForwardingItems() || (_previewData && _previewData->pendingTill >= 0)) {
|
||||
newScrollHeight -= st::replyHeight;
|
||||
}
|
||||
if (_kbShown) {
|
||||
newScrollHeight -= _kbScroll.height();
|
||||
int32 newScrollHeight = height();
|
||||
if (_botStart.isHidden()) {
|
||||
if (hist->readyForWork() && (!histPeer->chat || !histPeer->asChat()->forbidden)) {
|
||||
newScrollHeight -= (_field.height() + 2 * st::sendPadding);
|
||||
}
|
||||
if (_replyToId || _kbReplyTo || App::main()->hasForwardingItems() || (_previewData && _previewData->pendingTill >= 0)) {
|
||||
newScrollHeight -= st::replyHeight;
|
||||
}
|
||||
if (_kbShown) {
|
||||
newScrollHeight -= _kbScroll.height();
|
||||
}
|
||||
} else {
|
||||
newScrollHeight -= _botStart.height();
|
||||
}
|
||||
bool wasAtBottom = _scroll.scrollTop() + 1 > _scroll.scrollTopMax(), needResize = _scroll.width() != width() || _scroll.height() != newScrollHeight;
|
||||
if (needResize) {
|
||||
@ -4354,7 +4487,8 @@ void HistoryWidget::updateBotKeyboard() {
|
||||
if (!changed) return;
|
||||
|
||||
if (_keyboard.hasMarkup()) {
|
||||
if (wasVisible || _replyTo || (_field.getLastText().isEmpty() && !_kbWasHidden)) {
|
||||
if (_keyboard.singleUse() && _keyboard.forMsgId() == hist->lastKeyboardId && hist->lastKeyboardUsed) _kbWasHidden = true;
|
||||
if (_botStart.isHidden() && (wasVisible || _replyTo || (_field.getLastText().isEmpty() && !_kbWasHidden))) {
|
||||
if (!_showAnim.animating()) {
|
||||
_kbScroll.show();
|
||||
_attachEmoji.hide();
|
||||
@ -4365,7 +4499,10 @@ void HistoryWidget::updateBotKeyboard() {
|
||||
_field.setMaxHeight(st::maxFieldHeight - maxh);
|
||||
_kbShown = true;
|
||||
_kbReplyTo = hist->peer->chat ? App::histItemById(_keyboard.forMsgId()) : 0;
|
||||
if (_kbReplyTo && !_replyToId) _replyToText.setText(st::msgFont, _kbReplyTo->inDialogsText(), _textDlgOptions);
|
||||
if (_kbReplyTo && !_replyToId) {
|
||||
updateReplyToName();
|
||||
_replyToText.setText(st::msgFont, _kbReplyTo->inDialogsText(), _textDlgOptions);
|
||||
}
|
||||
} else {
|
||||
if (!_showAnim.animating()) {
|
||||
_kbScroll.hide();
|
||||
@ -4781,6 +4918,14 @@ void HistoryWidget::onDeleteContextSure() {
|
||||
App::wnd()->hideLayer();
|
||||
}
|
||||
|
||||
void HistoryWidget::onListEscapePressed() {
|
||||
if (_selCount && _list) {
|
||||
onClearSelected();
|
||||
} else {
|
||||
onCancel();
|
||||
}
|
||||
}
|
||||
|
||||
void HistoryWidget::onClearSelected() {
|
||||
if (_list) _list->clearSelectedItems();
|
||||
}
|
||||
@ -4818,7 +4963,7 @@ void HistoryWidget::updateTopBarSelection() {
|
||||
updateControlsVisibility();
|
||||
updateListSize();
|
||||
if (!App::wnd()->layerShown() && !App::passcoded()) {
|
||||
if (_selCount || _recording) {
|
||||
if (_selCount || _recording || !_botStart.isHidden()) {
|
||||
_list->setFocus();
|
||||
} else {
|
||||
_field.setFocus();
|
||||
|
@ -216,7 +216,10 @@ public:
|
||||
bool hasMarkup() const;
|
||||
|
||||
bool hoverStep(float64 ms);
|
||||
void resizeToWidth(int32 width);
|
||||
void resizeToWidth(int32 width, int32 maxOuterHeight);
|
||||
|
||||
bool maximizeSize() const;
|
||||
bool singleUse() const;
|
||||
|
||||
MsgId forMsgId() const {
|
||||
return _wasForMsgId;
|
||||
@ -233,6 +236,8 @@ private:
|
||||
void clearSelection();
|
||||
|
||||
MsgId _wasForMsgId;
|
||||
int32 _height, _maxOuterHeight;
|
||||
bool _maximizeSize, _singleUse;
|
||||
QTimer _cmdTipTimer;
|
||||
|
||||
QPoint _lastMousePos;
|
||||
@ -364,6 +369,7 @@ public:
|
||||
void newUnreadMsg(History *history, HistoryItem *item);
|
||||
void historyToDown(History *history);
|
||||
void historyWasRead(bool force = true);
|
||||
void historyCleared(History *history);
|
||||
|
||||
QRect historyRect() const;
|
||||
|
||||
@ -441,7 +447,10 @@ public:
|
||||
bool recordingStep(float64 ms);
|
||||
void stopRecording(bool send);
|
||||
|
||||
void onListEscapePressed();
|
||||
|
||||
void sendBotCommand(const QString &cmd, MsgId replyTo);
|
||||
void insertBotCommand(const QString &cmd);
|
||||
|
||||
~HistoryWidget();
|
||||
|
||||
@ -481,13 +490,14 @@ public slots:
|
||||
void onListScroll();
|
||||
void onHistoryToEnd();
|
||||
void onSend(bool ctrlShiftEnter = false, MsgId replyTo = -1);
|
||||
void onBotStart();
|
||||
|
||||
void onPhotoSelect();
|
||||
void onDocumentSelect();
|
||||
void onPhotoDrop(QDropEvent *e);
|
||||
void onDocumentDrop(QDropEvent *e);
|
||||
|
||||
void onKbToggle();
|
||||
void onKbToggle(bool manual = true);
|
||||
|
||||
void onPhotoReady();
|
||||
void onSendConfirmed();
|
||||
@ -597,7 +607,7 @@ private:
|
||||
|
||||
MentionsDropdown _attachMention;
|
||||
|
||||
FlatButton _send;
|
||||
FlatButton _send, _botStart;
|
||||
IconedButton _attachDocument, _attachPhoto, _attachEmoji, _kbShow, _kbHide;
|
||||
MessageField _field;
|
||||
Animation _recordAnim, _recordingAnim;
|
||||
|
@ -26,6 +26,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
#include "mainwidget.h"
|
||||
#include "boxes/confirmbox.h"
|
||||
#include "boxes/stickersetbox.h"
|
||||
#include "boxes/contactsbox.h"
|
||||
|
||||
#include "localstorage.h"
|
||||
|
||||
@ -973,6 +974,7 @@ void MainWidget::sendPreparedText(History *hist, const QString &text, MsgId repl
|
||||
void MainWidget::sendMessage(History *hist, const QString &text, MsgId replyTo) {
|
||||
readServerHistory(hist, false);
|
||||
hist->loadAround(0);
|
||||
if (history.peer())
|
||||
sendPreparedText(hist, history.prepareMessage(text), replyTo);
|
||||
}
|
||||
|
||||
@ -1026,6 +1028,10 @@ void MainWidget::sendBotCommand(const QString &cmd, MsgId replyTo) {
|
||||
history.sendBotCommand(cmd, replyTo);
|
||||
}
|
||||
|
||||
void MainWidget::insertBotCommand(const QString &cmd) {
|
||||
history.insertBotCommand(cmd);
|
||||
}
|
||||
|
||||
void MainWidget::searchMessages(const QString &query) {
|
||||
App::wnd()->hideMediaview();
|
||||
dialogs.searchMessages(query);
|
||||
@ -1779,6 +1785,7 @@ void MainWidget::showPeer(quint64 peerId, qint32 msgId, bool back, bool force) {
|
||||
if (profile || overview) {
|
||||
if (profile) {
|
||||
profile->hide();
|
||||
profile->clear();
|
||||
profile->deleteLater();
|
||||
profile->rpcInvalidate();
|
||||
profile = 0;
|
||||
@ -1902,6 +1909,7 @@ void MainWidget::showMediaOverview(PeerData *peer, MediaOverviewType type, bool
|
||||
}
|
||||
if (profile) {
|
||||
profile->hide();
|
||||
profile->clear();
|
||||
profile->deleteLater();
|
||||
profile->rpcInvalidate();
|
||||
profile = 0;
|
||||
@ -1949,6 +1957,7 @@ void MainWidget::showPeerProfile(PeerData *peer, bool back, int32 lastScrollTop,
|
||||
}
|
||||
if (profile) {
|
||||
profile->hide();
|
||||
profile->clear();
|
||||
profile->deleteLater();
|
||||
profile->rpcInvalidate();
|
||||
}
|
||||
@ -2073,6 +2082,10 @@ void MainWidget::historyWasRead() {
|
||||
history.historyWasRead(false);
|
||||
}
|
||||
|
||||
void MainWidget::historyCleared(History *hist) {
|
||||
history.historyCleared(hist);
|
||||
}
|
||||
|
||||
void MainWidget::animShow(const QPixmap &bgAnimCache, bool back) {
|
||||
_bgAnimCache = bgAnimCache;
|
||||
|
||||
@ -2536,7 +2549,7 @@ void MainWidget::openLocalUrl(const QString &url) {
|
||||
QRegularExpressionMatch m = QRegularExpression(qsl("^tg://resolve/?\\?domain=([a-zA-Z0-9\\.\\_]+)(&(start|startgroup)=([a-zA-Z0-9\\.\\_\\-]+))?(&|$)"), QRegularExpression::CaseInsensitiveOption).match(u);
|
||||
if (m.hasMatch()) {
|
||||
QString start = m.captured(3), startToken = m.captured(4);
|
||||
openUserByName(m.captured(1), (start == qsl("startgroup")), start, startToken);
|
||||
openUserByName(m.captured(1), (start == qsl("startgroup")), startToken);
|
||||
}
|
||||
} else if (u.startsWith(QLatin1String("tg://join"), Qt::CaseInsensitive)) {
|
||||
QRegularExpressionMatch m = QRegularExpression(qsl("^tg://join/?\\?invite=([a-zA-Z0-9\\.\\_\\-]+)(&|$)"), QRegularExpression::CaseInsensitiveOption).match(u);
|
||||
@ -2551,18 +2564,24 @@ void MainWidget::openLocalUrl(const QString &url) {
|
||||
}
|
||||
}
|
||||
|
||||
void MainWidget::openUserByName(const QString &username, bool toProfile, const QString &start, const QString &startToken) {
|
||||
void MainWidget::openUserByName(const QString &username, bool toProfile, const QString &startToken) {
|
||||
App::wnd()->hideMediaview();
|
||||
|
||||
UserData *user = App::userByName(username);
|
||||
if (user) {
|
||||
if (toProfile) {
|
||||
showPeerProfile(user);
|
||||
if (user->botInfo && !user->botInfo->cantJoinGroups && !startToken.isEmpty()) {
|
||||
user->botInfo->startGroupToken = startToken;
|
||||
App::wnd()->showLayer(new ContactsBox(user));
|
||||
} else {
|
||||
showPeerProfile(user);
|
||||
}
|
||||
} else {
|
||||
if (user->botInfo) user->botInfo->startToken = startToken;
|
||||
emit showPeerAsync(user->id, 0, false, true);
|
||||
}
|
||||
} else {
|
||||
MTP::send(MTPcontacts_ResolveUsername(MTP_string(username)), rpcDone(&MainWidget::usernameResolveDone, toProfile), rpcFail(&MainWidget::usernameResolveFail, username));
|
||||
MTP::send(MTPcontacts_ResolveUsername(MTP_string(username)), rpcDone(&MainWidget::usernameResolveDone, qMakePair(toProfile, startToken)), rpcFail(&MainWidget::usernameResolveFail, username));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2583,13 +2602,19 @@ void MainWidget::onStickersInstalled(uint64 setId) {
|
||||
history.stickersInstalled(setId);
|
||||
}
|
||||
|
||||
void MainWidget::usernameResolveDone(bool toProfile, const MTPUser &user) {
|
||||
void MainWidget::usernameResolveDone(QPair<bool, QString> toProfileStartToken, const MTPUser &result) {
|
||||
App::wnd()->hideLayer();
|
||||
UserData *u = App::feedUsers(MTP_vector<MTPUser>(1, user));
|
||||
if (toProfile) {
|
||||
showPeerProfile(u);
|
||||
UserData *user = App::feedUsers(MTP_vector<MTPUser>(1, result));
|
||||
if (toProfileStartToken.first) {
|
||||
if (user->botInfo && !user->botInfo->cantJoinGroups && !toProfileStartToken.second.isEmpty()) {
|
||||
user->botInfo->startGroupToken = toProfileStartToken.second;
|
||||
App::wnd()->showLayer(new ContactsBox(user));
|
||||
} else {
|
||||
showPeerProfile(user);
|
||||
}
|
||||
} else {
|
||||
showPeer(u->id, 0, false, true);
|
||||
if (user->botInfo) user->botInfo->startToken = toProfileStartToken.second;
|
||||
showPeer(user->id, 0, false, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -187,7 +187,7 @@ public:
|
||||
void start(const MTPUser &user);
|
||||
|
||||
void openLocalUrl(const QString &str);
|
||||
void openUserByName(const QString &name, bool toProfile = false, const QString &start = QString(), const QString &startToken = QString());
|
||||
void openUserByName(const QString &name, bool toProfile = false, const QString &startToken = QString());
|
||||
void joinGroupByHash(const QString &hash);
|
||||
void stickersBox(const MTPInputStickerSet &set);
|
||||
|
||||
@ -216,6 +216,7 @@ public:
|
||||
void dialogsToUp();
|
||||
void newUnreadMsg(History *history, HistoryItem *item);
|
||||
void historyWasRead();
|
||||
void historyCleared(History *history);
|
||||
|
||||
void peerBefore(const PeerData *inPeer, MsgId inMsg, PeerData *&outPeer, MsgId &outMsg);
|
||||
void peerAfter(const PeerData *inPeer, MsgId inMsg, PeerData *&outPeer, MsgId &outMsg);
|
||||
@ -297,6 +298,7 @@ public:
|
||||
void stopAnimActive();
|
||||
|
||||
void sendBotCommand(const QString &cmd, MsgId msgId);
|
||||
void insertBotCommand(const QString &cmd);
|
||||
|
||||
void searchMessages(const QString &query);
|
||||
void preloadOverviews(PeerData *peer);
|
||||
@ -450,7 +452,7 @@ private:
|
||||
void handleUpdates(const MTPUpdates &updates);
|
||||
bool updateFail(const RPCError &e);
|
||||
|
||||
void usernameResolveDone(bool toProfile, const MTPUser &user);
|
||||
void usernameResolveDone(QPair<bool, QString> toProfileStartToken, const MTPUser &result);
|
||||
bool usernameResolveFail(QString name, const RPCError &error);
|
||||
|
||||
void inviteCheckDone(QString hash, const MTPChatInvite &invite);
|
||||
|
@ -38,6 +38,10 @@ enum {
|
||||
MTPDuser_flag_bot = (1 << 14),
|
||||
MTPDuser_flag_bot_reads_all = (1 << 15),
|
||||
MTPDuser_flag_bot_cant_join = (1 << 16),
|
||||
|
||||
MTPDreplyKeyboardMarkup_flag_resize = (1 << 0),
|
||||
MTPDreplyKeyboardMarkup_flag_single_use = (1 << 1),
|
||||
MTPDreplyKeyboardMarkup_flag_ZERO = (1 << 31) // client side flag for zeroMarkup
|
||||
};
|
||||
|
||||
static const MTPReplyMarkup MTPnullMarkup = MTP_replyKeyboardMarkup(MTP_int(0), MTP_vector<MTPKeyboardButtonRow>(0));
|
||||
|
@ -2332,6 +2332,10 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
||||
to.add("{ inputMessagesFilterAudio }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
|
||||
break;
|
||||
|
||||
case mtpc_inputMessagesFilterAudioDocuments:
|
||||
to.add("{ inputMessagesFilterAudioDocuments }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
|
||||
break;
|
||||
|
||||
case mtpc_updateNewMessage:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
@ -4343,6 +4347,10 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_replyKeyboardHide:
|
||||
to.add("{ replyKeyboardHide }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
|
||||
break;
|
||||
|
||||
case mtpc_replyKeyboardMarkup:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
|
@ -199,6 +199,7 @@ enum {
|
||||
mtpc_inputMessagesFilterPhotoVideoDocuments = 0xd95e73bb,
|
||||
mtpc_inputMessagesFilterDocument = 0x9eddf188,
|
||||
mtpc_inputMessagesFilterAudio = 0xcfc87522,
|
||||
mtpc_inputMessagesFilterAudioDocuments = 0x5afbf764,
|
||||
mtpc_updateNewMessage = 0x1f2b0afd,
|
||||
mtpc_updateMessageID = 0x4e90bfd6,
|
||||
mtpc_updateDeleteMessages = 0xa20db0e5,
|
||||
@ -384,6 +385,7 @@ enum {
|
||||
mtpc_botInfo = 0x9cf585d,
|
||||
mtpc_keyboardButton = 0xa2fa4880,
|
||||
mtpc_keyboardButtonRow = 0x77608b83,
|
||||
mtpc_replyKeyboardHide = 0xced6ebbc,
|
||||
mtpc_replyKeyboardMarkup = 0x3502758c,
|
||||
mtpc_invokeAfterMsg = 0xcb9f372d,
|
||||
mtpc_invokeAfterMsgs = 0x3dc4b4f0,
|
||||
@ -4923,6 +4925,7 @@ private:
|
||||
friend MTPmessagesFilter MTP_inputMessagesFilterPhotoVideoDocuments();
|
||||
friend MTPmessagesFilter MTP_inputMessagesFilterDocument();
|
||||
friend MTPmessagesFilter MTP_inputMessagesFilterAudio();
|
||||
friend MTPmessagesFilter MTP_inputMessagesFilterAudioDocuments();
|
||||
|
||||
mtpTypeId _type;
|
||||
};
|
||||
@ -7981,32 +7984,39 @@ typedef MTPBoxed<MTPkeyboardButtonRow> MTPKeyboardButtonRow;
|
||||
|
||||
class MTPreplyMarkup : private mtpDataOwner {
|
||||
public:
|
||||
MTPreplyMarkup();
|
||||
MTPreplyMarkup(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_replyKeyboardMarkup) : mtpDataOwner(0) {
|
||||
MTPreplyMarkup() : mtpDataOwner(0), _type(0) {
|
||||
}
|
||||
MTPreplyMarkup(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) : mtpDataOwner(0), _type(0) {
|
||||
read(from, end, cons);
|
||||
}
|
||||
|
||||
MTPDreplyKeyboardMarkup &_replyKeyboardMarkup() {
|
||||
if (!data) throw mtpErrorUninitialized();
|
||||
if (_type != mtpc_replyKeyboardMarkup) throw mtpErrorWrongTypeId(_type, mtpc_replyKeyboardMarkup);
|
||||
split();
|
||||
return *(MTPDreplyKeyboardMarkup*)data;
|
||||
}
|
||||
const MTPDreplyKeyboardMarkup &c_replyKeyboardMarkup() const {
|
||||
if (!data) throw mtpErrorUninitialized();
|
||||
if (_type != mtpc_replyKeyboardMarkup) throw mtpErrorWrongTypeId(_type, mtpc_replyKeyboardMarkup);
|
||||
return *(const MTPDreplyKeyboardMarkup*)data;
|
||||
}
|
||||
|
||||
uint32 innerLength() const;
|
||||
mtpTypeId type() const;
|
||||
void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_replyKeyboardMarkup);
|
||||
void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons);
|
||||
void write(mtpBuffer &to) const;
|
||||
|
||||
typedef void ResponseType;
|
||||
|
||||
private:
|
||||
explicit MTPreplyMarkup(mtpTypeId type);
|
||||
explicit MTPreplyMarkup(MTPDreplyKeyboardMarkup *_data);
|
||||
|
||||
friend MTPreplyMarkup MTP_replyKeyboardHide();
|
||||
friend MTPreplyMarkup MTP_replyKeyboardMarkup(MTPint _flags, const MTPVector<MTPKeyboardButtonRow> &_rows);
|
||||
|
||||
mtpTypeId _type;
|
||||
};
|
||||
typedef MTPBoxed<MTPreplyMarkup> MTPReplyMarkup;
|
||||
|
||||
@ -21786,6 +21796,7 @@ inline void MTPmessagesFilter::read(const mtpPrime *&from, const mtpPrime *end,
|
||||
case mtpc_inputMessagesFilterPhotoVideoDocuments: _type = cons; break;
|
||||
case mtpc_inputMessagesFilterDocument: _type = cons; break;
|
||||
case mtpc_inputMessagesFilterAudio: _type = cons; break;
|
||||
case mtpc_inputMessagesFilterAudioDocuments: _type = cons; break;
|
||||
default: throw mtpErrorUnexpected(cons, "MTPmessagesFilter");
|
||||
}
|
||||
}
|
||||
@ -21802,6 +21813,7 @@ inline MTPmessagesFilter::MTPmessagesFilter(mtpTypeId type) : _type(type) {
|
||||
case mtpc_inputMessagesFilterPhotoVideoDocuments: break;
|
||||
case mtpc_inputMessagesFilterDocument: break;
|
||||
case mtpc_inputMessagesFilterAudio: break;
|
||||
case mtpc_inputMessagesFilterAudioDocuments: break;
|
||||
default: throw mtpErrorBadTypeId(type, "MTPmessagesFilter");
|
||||
}
|
||||
}
|
||||
@ -21826,6 +21838,9 @@ inline MTPmessagesFilter MTP_inputMessagesFilterDocument() {
|
||||
inline MTPmessagesFilter MTP_inputMessagesFilterAudio() {
|
||||
return MTPmessagesFilter(mtpc_inputMessagesFilterAudio);
|
||||
}
|
||||
inline MTPmessagesFilter MTP_inputMessagesFilterAudioDocuments() {
|
||||
return MTPmessagesFilter(mtpc_inputMessagesFilterAudioDocuments);
|
||||
}
|
||||
|
||||
inline uint32 MTPupdate::innerLength() const {
|
||||
switch (_type) {
|
||||
@ -25914,30 +25929,52 @@ inline MTPkeyboardButtonRow MTP_keyboardButtonRow(const MTPVector<MTPKeyboardBut
|
||||
return MTPkeyboardButtonRow(new MTPDkeyboardButtonRow(_buttons));
|
||||
}
|
||||
|
||||
inline MTPreplyMarkup::MTPreplyMarkup() : mtpDataOwner(new MTPDreplyKeyboardMarkup()) {
|
||||
}
|
||||
|
||||
inline uint32 MTPreplyMarkup::innerLength() const {
|
||||
const MTPDreplyKeyboardMarkup &v(c_replyKeyboardMarkup());
|
||||
return v.vflags.innerLength() + v.vrows.innerLength();
|
||||
switch (_type) {
|
||||
case mtpc_replyKeyboardMarkup: {
|
||||
const MTPDreplyKeyboardMarkup &v(c_replyKeyboardMarkup());
|
||||
return v.vflags.innerLength() + v.vrows.innerLength();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
inline mtpTypeId MTPreplyMarkup::type() const {
|
||||
return mtpc_replyKeyboardMarkup;
|
||||
if (!_type) throw mtpErrorUninitialized();
|
||||
return _type;
|
||||
}
|
||||
inline void MTPreplyMarkup::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) {
|
||||
if (cons != mtpc_replyKeyboardMarkup) throw mtpErrorUnexpected(cons, "MTPreplyMarkup");
|
||||
|
||||
if (!data) setData(new MTPDreplyKeyboardMarkup());
|
||||
MTPDreplyKeyboardMarkup &v(_replyKeyboardMarkup());
|
||||
v.vflags.read(from, end);
|
||||
v.vrows.read(from, end);
|
||||
if (cons != _type) setData(0);
|
||||
switch (cons) {
|
||||
case mtpc_replyKeyboardHide: _type = cons; break;
|
||||
case mtpc_replyKeyboardMarkup: _type = cons; {
|
||||
if (!data) setData(new MTPDreplyKeyboardMarkup());
|
||||
MTPDreplyKeyboardMarkup &v(_replyKeyboardMarkup());
|
||||
v.vflags.read(from, end);
|
||||
v.vrows.read(from, end);
|
||||
} break;
|
||||
default: throw mtpErrorUnexpected(cons, "MTPreplyMarkup");
|
||||
}
|
||||
}
|
||||
inline void MTPreplyMarkup::write(mtpBuffer &to) const {
|
||||
const MTPDreplyKeyboardMarkup &v(c_replyKeyboardMarkup());
|
||||
v.vflags.write(to);
|
||||
v.vrows.write(to);
|
||||
switch (_type) {
|
||||
case mtpc_replyKeyboardMarkup: {
|
||||
const MTPDreplyKeyboardMarkup &v(c_replyKeyboardMarkup());
|
||||
v.vflags.write(to);
|
||||
v.vrows.write(to);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
inline MTPreplyMarkup::MTPreplyMarkup(MTPDreplyKeyboardMarkup *_data) : mtpDataOwner(_data) {
|
||||
inline MTPreplyMarkup::MTPreplyMarkup(mtpTypeId type) : mtpDataOwner(0), _type(type) {
|
||||
switch (type) {
|
||||
case mtpc_replyKeyboardHide: break;
|
||||
case mtpc_replyKeyboardMarkup: setData(new MTPDreplyKeyboardMarkup()); break;
|
||||
default: throw mtpErrorBadTypeId(type, "MTPreplyMarkup");
|
||||
}
|
||||
}
|
||||
inline MTPreplyMarkup::MTPreplyMarkup(MTPDreplyKeyboardMarkup *_data) : mtpDataOwner(_data), _type(mtpc_replyKeyboardMarkup) {
|
||||
}
|
||||
inline MTPreplyMarkup MTP_replyKeyboardHide() {
|
||||
return MTPreplyMarkup(mtpc_replyKeyboardHide);
|
||||
}
|
||||
inline MTPreplyMarkup MTP_replyKeyboardMarkup(MTPint _flags, const MTPVector<MTPKeyboardButtonRow> &_rows) {
|
||||
return MTPreplyMarkup(new MTPDreplyKeyboardMarkup(_flags, _rows));
|
||||
|
@ -324,6 +324,7 @@ inputMessagesFilterPhotoVideo#56e9f0e4 = MessagesFilter;
|
||||
inputMessagesFilterPhotoVideoDocuments#d95e73bb = MessagesFilter;
|
||||
inputMessagesFilterDocument#9eddf188 = MessagesFilter;
|
||||
inputMessagesFilterAudio#cfc87522 = MessagesFilter;
|
||||
inputMessagesFilterAudioDocuments#5afbf764 = MessagesFilter;
|
||||
|
||||
updateNewMessage#1f2b0afd message:Message pts:int pts_count:int = Update;
|
||||
updateMessageID#4e90bfd6 id:int random_id:long = Update;
|
||||
@ -602,6 +603,7 @@ keyboardButton#a2fa4880 text:string = KeyboardButton;
|
||||
|
||||
keyboardButtonRow#77608b83 buttons:Vector<KeyboardButton> = KeyboardButtonRow;
|
||||
|
||||
replyKeyboardHide#ced6ebbc = ReplyMarkup;
|
||||
replyKeyboardMarkup#3502758c flags:# rows:Vector<KeyboardButtonRow> = ReplyMarkup;
|
||||
|
||||
---functions---
|
||||
|
@ -469,6 +469,9 @@ void ProfileInner::reorderParticipants() {
|
||||
}
|
||||
}
|
||||
|
||||
void ProfileInner::start() {
|
||||
}
|
||||
|
||||
bool ProfileInner::event(QEvent *e) {
|
||||
if (e->type() == QEvent::MouseMove) {
|
||||
_lastPos = static_cast<QMouseEvent*>(e)->globalPos();
|
||||
@ -1220,6 +1223,7 @@ bool ProfileWidget::animStep(float64 ms) {
|
||||
_bgAnimCache = _animCache = _animTopBarCache = _bgAnimTopBarCache = QPixmap();
|
||||
App::main()->topBar()->stopAnim();
|
||||
_scroll.show();
|
||||
_inner.start();
|
||||
activate();
|
||||
} else {
|
||||
a_bgCoord.update(dt1, st::introHideFunc);
|
||||
@ -1249,6 +1253,12 @@ void ProfileWidget::mediaOverviewUpdated(PeerData *peer) {
|
||||
_inner.mediaOverviewUpdated(peer);
|
||||
}
|
||||
|
||||
void ProfileWidget::clear() {
|
||||
if (_inner.peer() && !_inner.peer()->chat && _inner.peer()->asUser()->botInfo) {
|
||||
_inner.peer()->asUser()->botInfo->startGroupToken = QString();
|
||||
}
|
||||
}
|
||||
|
||||
ProfileWidget::~ProfileWidget() {
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,8 @@ public:
|
||||
|
||||
ProfileInner(ProfileWidget *profile, ScrollArea *scroll, const PeerData *peer);
|
||||
|
||||
void start();
|
||||
|
||||
bool event(QEvent *e);
|
||||
void paintEvent(QPaintEvent *e);
|
||||
void mouseMoveEvent(QMouseEvent *e);
|
||||
@ -200,6 +202,7 @@ public:
|
||||
void updateNotifySettings();
|
||||
void mediaOverviewUpdated(PeerData *peer);
|
||||
|
||||
void clear();
|
||||
~ProfileWidget();
|
||||
|
||||
public slots:
|
||||
|
@ -132,6 +132,8 @@ struct BotInfo {
|
||||
QString shareText, description;
|
||||
QList<BotCommand> commands;
|
||||
Text text; // description
|
||||
|
||||
QString startToken, startGroupToken;
|
||||
};
|
||||
|
||||
struct PhotoData;
|
||||
@ -180,6 +182,8 @@ struct ChatData : public PeerData {
|
||||
CanKick cankick;
|
||||
typedef QList<UserData*> LastAuthors;
|
||||
LastAuthors lastAuthors;
|
||||
typedef QMap<UserData*, bool> MarkupSenders;
|
||||
MarkupSenders markupSenders;
|
||||
int32 botStatus; // -1 - no bots, 0 - unknown, 1 - one bot, that sees all history, 2 - other
|
||||
ImagePtr photoFull;
|
||||
PhotoId photoId;
|
||||
|
@ -11,7 +11,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>0.8.26</string>
|
||||
<string>0.8.27</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
|
||||
<key>CFBundleSignature</key>
|
||||
|
Binary file not shown.
@ -1701,7 +1701,7 @@
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 0.8.26;
|
||||
CURRENT_PROJECT_VERSION = 0.8.27;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
@ -1719,7 +1719,7 @@
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
COPY_PHASE_STRIP = YES;
|
||||
CURRENT_PROJECT_VERSION = 0.8.26;
|
||||
CURRENT_PROJECT_VERSION = 0.8.27;
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
||||
GCC_OPTIMIZATION_LEVEL = fast;
|
||||
GCC_PREFIX_HEADER = ./SourceFiles/stdafx.h;
|
||||
@ -1745,10 +1745,10 @@
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
CODE_SIGN_IDENTITY = "";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 0.8.26;
|
||||
CURRENT_PROJECT_VERSION = 0.8.27;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DYLIB_COMPATIBILITY_VERSION = 0.8;
|
||||
DYLIB_CURRENT_VERSION = 0.8.26;
|
||||
DYLIB_CURRENT_VERSION = 0.8.27;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
FRAMEWORK_SEARCH_PATHS = "";
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
|
||||
@ -1888,10 +1888,10 @@
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
CODE_SIGN_IDENTITY = "";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 0.8.26;
|
||||
CURRENT_PROJECT_VERSION = 0.8.27;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DYLIB_COMPATIBILITY_VERSION = 0.8;
|
||||
DYLIB_CURRENT_VERSION = 0.8.26;
|
||||
DYLIB_CURRENT_VERSION = 0.8.27;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
FRAMEWORK_SEARCH_PATHS = "";
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
|
||||
|
@ -1,2 +1,2 @@
|
||||
echo 8026 0.8.26 1
|
||||
echo 8027 0.8.27 1
|
||||
# AppVersion AppVersionStr DevChannel
|
||||
|
Loading…
Reference in New Issue
Block a user