metalang tags gen fixed, links parsing in rich text fixed, custom keyboard hiding saved in history

This commit is contained in:
John Preston 2015-11-23 18:34:38 +03:00
parent d6bcab07ef
commit 46df0f32c8
9 changed files with 161 additions and 98 deletions

View File

@ -276,11 +276,11 @@ QString escapeCpp(const QByteArray &key, QString value) {
} }
res.append(' ').append('u').append('"').append('\\').append('x').append(QString("%1").arg(ch->unicode(), 4, 16, QChar('0'))).append('"'); res.append(' ').append('u').append('"').append('\\').append('x').append(QString("%1").arg(ch->unicode(), 4, 16, QChar('0'))).append('"');
} else { } else {
if (ch->unicode() == '\\' || ch->unicode() == '\n' || ch->unicode() == '\r' || ch->unicode() == '"') {
if (!instr) { if (!instr) {
res.append(' ').append('u').append('"'); res.append(' ').append('u').append('"');
instr = true; instr = true;
} }
if (ch->unicode() == '\\' || ch->unicode() == '\n' || ch->unicode() == '\r' || ch->unicode() == '"') {
res.append('\\'); res.append('\\');
if (ch->unicode() == '\\' || ch->unicode() == '"') { if (ch->unicode() == '\\' || ch->unicode() == '"') {
res.append(*ch); res.append(*ch);
@ -294,16 +294,26 @@ QString escapeCpp(const QByteArray &key, QString value) {
if (ch + 3 >= e || (ch + 1)->unicode() != TextCommandLangTag || (ch + 2)->unicode() > 0x007F || (ch + 2)->unicode() < 0x0020 || *(ch + 3) != TextCommand) { if (ch + 3 >= e || (ch + 1)->unicode() != TextCommandLangTag || (ch + 2)->unicode() > 0x007F || (ch + 2)->unicode() < 0x0020 || *(ch + 3) != TextCommand) {
throw Exception(QString("Bad value for key '%1'").arg(QLatin1String(key))); throw Exception(QString("Bad value for key '%1'").arg(QLatin1String(key)));
} else { } else {
if (instr) {
res.append('"');
instr = false;
}
res.append(' ').append('u').append('"');
res.append('\\').append('x').append(QString("%1").arg(ch->unicode(), 2, 16, QChar('0'))); res.append('\\').append('x').append(QString("%1").arg(ch->unicode(), 2, 16, QChar('0')));
res.append('\\').append('x').append(QString("%1").arg((ch + 1)->unicode(), 2, 16, QChar('0'))); res.append('\\').append('x').append(QString("%1").arg((ch + 1)->unicode(), 2, 16, QChar('0')));
res.append('\\').append('x').append(QString("%1").arg((ch + 2)->unicode(), 2, 16, QChar('0'))); res.append('\\').append('x').append(QString("%1").arg((ch + 2)->unicode(), 2, 16, QChar('0')));
res.append('\\').append('x').append(QString("%1").arg((ch + 3)->unicode(), 2, 16, QChar('0'))); res.append('\\').append('x').append(QString("%1").arg((ch + 3)->unicode(), 2, 16, QChar('0')));
res.append('"');
ch += 3; ch += 3;
} }
} else { } else {
throw Exception(QString("Bad value for key '%1'").arg(QLatin1String(key))); throw Exception(QString("Bad value for key '%1'").arg(QLatin1String(key)));
} }
} else { } else {
if (!instr) {
res.append(' ').append('u').append('"');
instr = true;
}
res.append(*ch); res.append(*ch);
} }
} }

View File

@ -354,13 +354,15 @@ public:
} }
} }
void checkCommand() { bool checkCommand() {
QChar c = ((ptr < end) ? *ptr : 0); bool result = false;
while (c == TextCommand) { for (QChar c = ((ptr < end) ? *ptr : 0); c == TextCommand; c = ((ptr < end) ? *ptr : 0)) {
if (!readCommand()) { if (!readCommand()) {
break; break;
} }
result = true;
} }
return result;
} }
void checkEntities() { void checkEntities() {
@ -694,7 +696,11 @@ public:
while (waitingEntity != entitiesEnd && waitingEntity->length <= 0) ++waitingEntity; while (waitingEntity != entitiesEnd && waitingEntity->length <= 0) ++waitingEntity;
for (; ptr <= end; ++ptr) { for (; ptr <= end; ++ptr) {
checkEntities(); checkEntities();
if (rich) checkCommand(); if (rich) {
if (checkCommand()) {
checkEntities();
}
}
parseCurrentChar(); parseCurrentChar();
parseEmojiFromCurrent(); parseEmojiFromCurrent();
@ -4476,6 +4482,47 @@ goodCanBreakEntity = canBreakEntity;\
return true; return true;
} }
bool textcmdStartsLink(const QChar *start, int32 len, int32 commandOffset) {
if (commandOffset + 2 < len) {
if (*(start + commandOffset + 1) == TextCommandLinkIndex) {
return (*(start + commandOffset + 2) != 0);
}
return (*(start + commandOffset + 1) != TextCommandLinkText);
}
return false;
}
bool checkTagStartInCommand(const QChar *start, int32 len, int32 tagStart, int32 &commandOffset, bool &commandIsLink, bool &inLink) {
bool inCommand = false;
const QChar *commandEnd = start + commandOffset;
while (commandOffset < len && tagStart > commandOffset) { // skip commands, evaluating are we in link or not
commandEnd = textSkipCommand(start + commandOffset, start + len);
if (commandEnd > start + commandOffset) {
if (tagStart < (commandEnd - start)) {
inCommand = true;
break;
}
for (commandOffset = commandEnd - start; commandOffset < len; ++commandOffset) {
if (*(start + commandOffset) == TextCommand) {
inLink = commandIsLink;
commandIsLink = textcmdStartsLink(start, len, commandOffset);
break;
}
}
if (commandOffset >= len) {
inLink = commandIsLink;
commandIsLink = false;
}
} else {
break;
}
}
if (inCommand) {
commandOffset = commandEnd - start;
}
return inCommand;
}
EntitiesInText textParseEntities(QString &text, int32 flags, bool rich) { // some code is duplicated in flattextarea.cpp! EntitiesInText textParseEntities(QString &text, int32 flags, bool rich) { // some code is duplicated in flattextarea.cpp!
EntitiesInText result, mono; EntitiesInText result, mono;
@ -4487,15 +4534,22 @@ EntitiesInText textParseEntities(QString &text, int32 flags, bool rich) { // som
if (withMono) { // parse mono entities (code and pre) if (withMono) { // parse mono entities (code and pre)
QString newText; QString newText;
int32 offset = 0, matchOffset = offset, len = text.size(), nextCmd = rich ? 0 : len; int32 offset = 0, matchOffset = offset, len = text.size(), commandOffset = rich ? 0 : len;
bool inLink = false, commandIsLink = false;
const QChar *start = text.constData(); const QChar *start = text.constData();
for (; matchOffset < len;) { for (; matchOffset < len;) {
if (nextCmd <= matchOffset) { if (commandOffset <= matchOffset) {
for (nextCmd = matchOffset; nextCmd < len; ++nextCmd) { for (commandOffset = matchOffset; commandOffset < len; ++commandOffset) {
if (*(start + nextCmd) == TextCommand) { if (*(start + commandOffset) == TextCommand) {
inLink = commandIsLink;
commandIsLink = textcmdStartsLink(start, len, commandOffset);
break; break;
} }
} }
if (commandOffset >= len) {
inLink = commandIsLink;
commandIsLink = false;
}
} }
QRegularExpressionMatch mPre = _rePre.match(text, matchOffset); QRegularExpressionMatch mPre = _rePre.match(text, matchOffset);
QRegularExpressionMatch mCode = _reCode.match(text, matchOffset), mTag; QRegularExpressionMatch mCode = _reCode.match(text, matchOffset), mTag;
@ -4533,13 +4587,12 @@ EntitiesInText textParseEntities(QString &text, int32 flags, bool rich) { // som
tagEnd = codeEnd; tagEnd = codeEnd;
mTag = mCode; mTag = mCode;
} }
if (tagStart > nextCmd) {
const QChar *after = textSkipCommand(start + nextCmd, start + len); bool inCommand = checkTagStartInCommand(start, len, tagStart, commandOffset, commandIsLink, inLink);
if (after > start + nextCmd && tagStart < (after - start)) { if (inCommand || inLink) {
nextCmd = matchOffset = after - start; matchOffset = commandOffset;
continue; continue;
} }
}
if (newText.isEmpty()) newText.reserve(text.size()); if (newText.isEmpty()) newText.reserve(text.size());
@ -4594,12 +4647,15 @@ EntitiesInText textParseEntities(QString &text, int32 flags, bool rich) { // som
int32 monoEntity = 0, monoCount = mono.size(), monoTill = 0; int32 monoEntity = 0, monoCount = mono.size(), monoTill = 0;
initLinkSets(); initLinkSets();
int32 len = text.size(), nextCmd = rich ? 0 : len; int32 len = text.size(), commandOffset = rich ? 0 : len;
bool inLink = false, commandIsLink = false;
const QChar *start = text.constData(), *end = start + text.size(); const QChar *start = text.constData(), *end = start + text.size();
for (int32 offset = 0, matchOffset = offset, mentionSkip = 0; offset < len;) { for (int32 offset = 0, matchOffset = offset, mentionSkip = 0; offset < len;) {
if (nextCmd <= offset) { if (commandOffset <= offset) {
for (nextCmd = offset; nextCmd < len; ++nextCmd) { for (commandOffset = offset; commandOffset < len; ++commandOffset) {
if (*(start + nextCmd) == TextCommand) { if (*(start + commandOffset) == TextCommand) {
inLink = commandIsLink;
commandIsLink = textcmdStartsLink(start, len, commandOffset);
break; break;
} }
} }
@ -4669,48 +4725,41 @@ EntitiesInText textParseEntities(QString &text, int32 flags, bool rich) { // som
mDomain = mExplicitDomain; mDomain = mExplicitDomain;
} }
if (mentionStart < hashtagStart && mentionStart < domainStart && mentionStart < botCommandStart) { if (mentionStart < hashtagStart && mentionStart < domainStart && mentionStart < botCommandStart) {
if (mentionStart > nextCmd) { bool inCommand = checkTagStartInCommand(start, len, mentionStart, commandOffset, commandIsLink, inLink);
const QChar *after = textSkipCommand(start + nextCmd, start + len); if (inCommand || inLink) {
if (after > start + nextCmd && mentionStart < (after - start)) { offset = matchOffset = commandOffset;
nextCmd = offset = matchOffset = after - start;
continue; continue;
} }
}
lnkType = EntityInTextMention; lnkType = EntityInTextMention;
lnkStart = mentionStart; lnkStart = mentionStart;
lnkLength = mentionEnd - mentionStart; lnkLength = mentionEnd - mentionStart;
} else if (hashtagStart < domainStart && hashtagStart < botCommandStart) { } else if (hashtagStart < domainStart && hashtagStart < botCommandStart) {
if (hashtagStart > nextCmd) { bool inCommand = checkTagStartInCommand(start, len, hashtagStart, commandOffset, commandIsLink, inLink);
const QChar *after = textSkipCommand(start + nextCmd, start + len); if (inCommand || inLink) {
if (after > start + nextCmd && hashtagStart < (after - start)) { offset = matchOffset = commandOffset;
nextCmd = offset = matchOffset = after - start;
continue; continue;
} }
}
lnkType = EntityInTextHashtag; lnkType = EntityInTextHashtag;
lnkStart = hashtagStart; lnkStart = hashtagStart;
lnkLength = hashtagEnd - hashtagStart; lnkLength = hashtagEnd - hashtagStart;
} else if (botCommandStart < domainStart) { } else if (botCommandStart < domainStart) {
if (botCommandStart > nextCmd) { bool inCommand = checkTagStartInCommand(start, len, botCommandStart, commandOffset, commandIsLink, inLink);
const QChar *after = textSkipCommand(start + nextCmd, start + len); if (inCommand || inLink) {
if (after > start + nextCmd && botCommandStart < (after - start)) { offset = matchOffset = commandOffset;
nextCmd = offset = matchOffset = after - start;
continue; continue;
} }
}
lnkType = EntityInTextBotCommand; lnkType = EntityInTextBotCommand;
lnkStart = botCommandStart; lnkStart = botCommandStart;
lnkLength = botCommandEnd - botCommandStart; lnkLength = botCommandEnd - botCommandStart;
} else { } else {
if (domainStart > nextCmd) { bool inCommand = checkTagStartInCommand(start, len, domainStart, commandOffset, commandIsLink, inLink);
const QChar *after = textSkipCommand(start + nextCmd, start + len); if (inCommand || inLink) {
if (after > start + nextCmd && domainStart < (after - start)) { offset = matchOffset = commandOffset;
nextCmd = offset = matchOffset = after - start;
continue; continue;
} }
}
QString protocol = mDomain.captured(1).toLower(); QString protocol = mDomain.captured(1).toLower();
QString topDomain = mDomain.captured(3).toLower(); QString topDomain = mDomain.captured(3).toLower();

View File

@ -369,6 +369,7 @@ History::History(const PeerId &peerId) : width(0), height(0)
, lastKeyboardInited(false) , lastKeyboardInited(false)
, lastKeyboardUsed(false) , lastKeyboardUsed(false)
, lastKeyboardId(0) , lastKeyboardId(0)
, lastKeyboardHiddenId(0)
, lastKeyboardFrom(0) , lastKeyboardFrom(0)
, sendRequestId(0) , sendRequestId(0)
, textCachedFor(0) , textCachedFor(0)
@ -388,6 +389,7 @@ void History::clearLastKeyboard() {
lastKeyboardInited = true; lastKeyboardInited = true;
lastKeyboardId = 0; lastKeyboardId = 0;
lastKeyboardFrom = 0; lastKeyboardFrom = 0;
lastKeyboardHiddenId = 0;
} }
bool History::updateTyping(uint64 ms, uint32 dots, bool force) { bool History::updateTyping(uint64 ms, uint32 dots, bool force) {
@ -6589,11 +6591,13 @@ void HistoryMessage::setMedia(const MTPMessageMedia *media, bool allowEmitResize
void HistoryMessage::setText(const QString &text, const EntitiesInText &entities) { void HistoryMessage::setText(const QString &text, const EntitiesInText &entities) {
if (!_media || !text.isEmpty()) { // !justMedia() if (!_media || !text.isEmpty()) { // !justMedia()
textstyleSet(&((out() && !fromChannel()) ? st::outTextStyle : st::inTextStyle));
if (_media && _media->isDisplayed()) { if (_media && _media->isDisplayed()) {
_text.setMarkedText(st::msgFont, text, entities, itemTextOptions(this)); _text.setMarkedText(st::msgFont, text, entities, itemTextOptions(this));
} else { } else {
_text.setMarkedText(st::msgFont, text + skipBlock(), entities, itemTextOptions(this)); _text.setMarkedText(st::msgFont, text + skipBlock(), entities, itemTextOptions(this));
} }
textstyleRestore();
if (id > 0) { if (id > 0) {
for (int32 i = 0, l = entities.size(); i != l; ++i) { for (int32 i = 0, l = entities.size(); i != l; ++i) {
if (entities.at(i).type == EntityInTextUrl || entities.at(i).type == EntityInTextCustomUrl || entities.at(i).type == EntityInTextEmail) { if (entities.at(i).type == EntityInTextUrl || entities.at(i).type == EntityInTextCustomUrl || entities.at(i).type == EntityInTextEmail) {
@ -6810,6 +6814,8 @@ void HistoryMessage::draw(Painter &p, uint32 selection) const {
} }
HistoryMessage::drawInfo(p, r.x() + r.width(), r.y() + r.height(), selected, InfoDisplayDefault); HistoryMessage::drawInfo(p, r.x() + r.width(), r.y() + r.height(), selected, InfoDisplayDefault);
} }
textstyleRestore();
} }
void HistoryMessage::drawMessageText(Painter &p, const QRect &trect, uint32 selection) const { void HistoryMessage::drawMessageText(Painter &p, const QRect &trect, uint32 selection) const {
@ -6818,8 +6824,6 @@ void HistoryMessage::drawMessageText(Painter &p, const QRect &trect, uint32 sele
uint16 selectedFrom = (selection == FullItemSel) ? 0 : (selection >> 16) & 0xFFFF; uint16 selectedFrom = (selection == FullItemSel) ? 0 : (selection >> 16) & 0xFFFF;
uint16 selectedTo = (selection == FullItemSel) ? 0 : selection & 0xFFFF; uint16 selectedTo = (selection == FullItemSel) ? 0 : selection & 0xFFFF;
_text.draw(p, trect.x(), trect.y(), trect.width(), Qt::AlignLeft, 0, -1, selectedFrom, selectedTo); _text.draw(p, trect.x(), trect.y(), trect.width(), Qt::AlignLeft, 0, -1, selectedFrom, selectedTo);
textstyleRestore();
} }
int32 HistoryMessage::resize(int32 width) { int32 HistoryMessage::resize(int32 width) {
@ -6837,7 +6841,9 @@ int32 HistoryMessage::resize(int32 width) {
int32 nwidth = qMax(width - st::msgPadding.left() - st::msgPadding.right(), 0); int32 nwidth = qMax(width - st::msgPadding.left() - st::msgPadding.right(), 0);
if (nwidth != _textWidth) { if (nwidth != _textWidth) {
_textWidth = nwidth; _textWidth = nwidth;
textstyleSet(&((out() && !fromChannel()) ? st::outTextStyle : st::inTextStyle));
_textHeight = _text.countHeight(nwidth); _textHeight = _text.countHeight(nwidth);
textstyleRestore();
} }
if (width >= _maxw) { if (width >= _maxw) {
_height = _minh; _height = _minh;
@ -6972,8 +6978,10 @@ void HistoryMessage::getStateFromMessageText(TextLinkPtr &lnk, HistoryCursorStat
} }
trect.setBottom(trect.bottom() - _media->height() - st::msgPadding.bottom()); trect.setBottom(trect.bottom() - _media->height() - st::msgPadding.bottom());
} }
textstyleSet(&((out() && !fromChannel()) ? st::outTextStyle : st::inTextStyle));
bool inText = false; bool inText = false;
_text.getState(lnk, inText, x - trect.x(), y - trect.y(), trect.width()); _text.getState(lnk, inText, x - trect.x(), y - trect.y(), trect.width());
textstyleRestore();
if (inDate) { if (inDate) {
state = HistoryInDateCursorState; state = HistoryInDateCursorState;
@ -7022,7 +7030,9 @@ void HistoryMessage::getSymbol(uint16 &symbol, bool &after, bool &upon, int32 x,
if (_media && _media->isDisplayed()) { if (_media && _media->isDisplayed()) {
trect.setBottom(trect.bottom() - _media->height() - st::msgPadding.bottom()); trect.setBottom(trect.bottom() - _media->height() - st::msgPadding.bottom());
} }
textstyleSet(&((out() && !fromChannel()) ? st::outTextStyle : st::inTextStyle));
_text.getSymbol(symbol, after, upon, x - trect.x(), y - trect.y(), trect.width()); _text.getSymbol(symbol, after, upon, x - trect.x(), y - trect.y(), trect.width());
textstyleRestore();
} }
void HistoryMessage::drawInDialog(Painter &p, const QRect &r, bool act, const HistoryItem *&cacheFor, Text &cache) const { void HistoryMessage::drawInDialog(Painter &p, const QRect &r, bool act, const HistoryItem *&cacheFor, Text &cache) const {
@ -7750,7 +7760,9 @@ void HistoryServiceMsg::setMessageByAction(const MTPmessageAction &action) {
default: from = QString(); break; default: from = QString(); break;
} }
textstyleSet(&st::serviceTextStyle);
_text.setText(st::msgServiceFont, text, _historySrvOptions); _text.setText(st::msgServiceFont, text, _historySrvOptions);
textstyleRestore();
if (!from.isEmpty()) { if (!from.isEmpty()) {
_text.setLink(1, TextLinkPtr(new PeerLink(_from))); _text.setLink(1, TextLinkPtr(new PeerLink(_from)));
} }
@ -7800,7 +7812,9 @@ QString HistoryServiceMsg::inReplyText() const {
} }
void HistoryServiceMsg::setServiceText(const QString &text) { void HistoryServiceMsg::setServiceText(const QString &text) {
textstyleSet(&st::serviceTextStyle);
_text.setText(st::msgServiceFont, text, _historySrvOptions); _text.setText(st::msgServiceFont, text, _historySrvOptions);
textstyleRestore();
initDimensions(); initDimensions();
} }
@ -7856,7 +7870,9 @@ int32 HistoryServiceMsg::resize(int32 width) {
int32 nwidth = qMax(width - st::msgPadding.left() - st::msgPadding.right(), 0); int32 nwidth = qMax(width - st::msgPadding.left() - st::msgPadding.right(), 0);
if (nwidth != _textWidth) { if (nwidth != _textWidth) {
_textWidth = nwidth; _textWidth = nwidth;
textstyleSet(&st::serviceTextStyle);
_textHeight = _text.countHeight(nwidth); _textHeight = _text.countHeight(nwidth);
textstyleRestore();
} }
if (width >= _maxw) { if (width >= _maxw) {
_height = _minh; _height = _minh;
@ -7892,8 +7908,10 @@ void HistoryServiceMsg::getState(TextLinkPtr &lnk, HistoryCursorState &state, in
} }
QRect trect(QRect(left, st::msgServiceMargin.top(), width, height).marginsAdded(-st::msgServicePadding)); QRect trect(QRect(left, st::msgServiceMargin.top(), width, height).marginsAdded(-st::msgServicePadding));
if (trect.contains(x, y)) { if (trect.contains(x, y)) {
textstyleSet(&st::serviceTextStyle);
bool inText = false; bool inText = false;
_text.getState(lnk, inText, x - trect.x(), y - trect.y(), trect.width(), Qt::AlignCenter); _text.getState(lnk, inText, x - trect.x(), y - trect.y(), trect.width(), Qt::AlignCenter);
textstyleRestore();
state = inText ? HistoryInTextCursorState : HistoryDefaultCursorState; state = inText ? HistoryInTextCursorState : HistoryDefaultCursorState;
} else if (_media) { } else if (_media) {
_media->getState(lnk, state, x - st::msgServiceMargin.left() - (width - _media->maxWidth()) / 2, y - st::msgServiceMargin.top() - height - st::msgServiceMargin.top(), this); _media->getState(lnk, state, x - st::msgServiceMargin.left() - (width - _media->maxWidth()) / 2, y - st::msgServiceMargin.top() - height - st::msgServiceMargin.top(), this);
@ -7912,7 +7930,9 @@ void HistoryServiceMsg::getSymbol(uint16 &symbol, bool &after, bool &upon, int32
height -= st::msgServiceMargin.top() + _media->height(); height -= st::msgServiceMargin.top() + _media->height();
} }
QRect trect(QRect(left, st::msgServiceMargin.top(), width, height).marginsAdded(-st::msgServicePadding)); QRect trect(QRect(left, st::msgServiceMargin.top(), width, height).marginsAdded(-st::msgServicePadding));
return _text.getSymbol(symbol, after, upon, x - trect.x(), y - trect.y(), trect.width(), Qt::AlignCenter); textstyleSet(&st::serviceTextStyle);
_text.getSymbol(symbol, after, upon, x - trect.x(), y - trect.y(), trect.width(), Qt::AlignCenter);
textstyleRestore();
} }
void HistoryServiceMsg::drawInDialog(Painter &p, const QRect &r, bool act, const HistoryItem *&cacheFor, Text &cache) const { void HistoryServiceMsg::drawInDialog(Painter &p, const QRect &r, bool act, const HistoryItem *&cacheFor, Text &cache) const {
@ -8033,12 +8053,14 @@ void HistoryCollapse::getState(TextLinkPtr &lnk, HistoryCursorState &state, int3
HistoryJoined::HistoryJoined(History *history, HistoryBlock *block, const QDateTime &inviteDate, UserData *inviter, int32 flags) : HistoryJoined::HistoryJoined(History *history, HistoryBlock *block, const QDateTime &inviteDate, UserData *inviter, int32 flags) :
HistoryServiceMsg(history, block, clientMsgId(), inviteDate, QString(), flags) { HistoryServiceMsg(history, block, clientMsgId(), inviteDate, QString(), flags) {
textstyleSet(&st::serviceTextStyle);
if (peerToUser(inviter->id) == MTP::authedId()) { if (peerToUser(inviter->id) == MTP::authedId()) {
_text.setText(st::msgServiceFont, lang(history->isMegagroup() ? lng_action_you_joined_group : lng_action_you_joined), _historySrvOptions); _text.setText(st::msgServiceFont, lang(history->isMegagroup() ? lng_action_you_joined_group : lng_action_you_joined), _historySrvOptions);
} else { } else {
_text.setText(st::msgServiceFont, history->isMegagroup() ? lng_action_add_you_group(lt_from, textcmdLink(1, inviter->name)) : lng_action_add_you(lt_from, textcmdLink(1, inviter->name)), _historySrvOptions); _text.setText(st::msgServiceFont, history->isMegagroup() ? lng_action_add_you_group(lt_from, textcmdLink(1, inviter->name)) : lng_action_add_you(lt_from, textcmdLink(1, inviter->name)), _historySrvOptions);
_text.setLink(1, TextLinkPtr(new PeerLink(inviter))); _text.setLink(1, TextLinkPtr(new PeerLink(inviter)));
} }
textstyleRestore();
} }
HistoryUnreadBar::HistoryUnreadBar(History *history, HistoryBlock *block, int32 count, const QDateTime &date) : HistoryItem(history, block, clientMsgId(), 0, date, 0), freezed(false) { HistoryUnreadBar::HistoryUnreadBar(History *history, HistoryBlock *block, int32 count, const QDateTime &date) : HistoryItem(history, block, clientMsgId(), 0, date, 0), freezed(false) {

View File

@ -320,7 +320,7 @@ public:
bool mute; bool mute;
bool lastKeyboardInited, lastKeyboardUsed; bool lastKeyboardInited, lastKeyboardUsed;
MsgId lastKeyboardId; MsgId lastKeyboardId, lastKeyboardHiddenId;
PeerId lastKeyboardFrom; PeerId lastKeyboardFrom;
mtpRequestId sendRequestId; mtpRequestId sendRequestId;

View File

@ -2595,7 +2595,6 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent)
, a_recordOver(0, 0), a_recordDown(0, 0), a_recordCancel(st::recordCancel->c, st::recordCancel->c) , a_recordOver(0, 0), a_recordDown(0, 0), a_recordCancel(st::recordCancel->c, st::recordCancel->c)
, _recordCancelWidth(st::recordFont->width(lang(lng_record_cancel))) , _recordCancelWidth(st::recordFont->width(lang(lng_record_cancel)))
, _kbShown(false) , _kbShown(false)
, _kbWasHidden(false)
, _kbReplyTo(0) , _kbReplyTo(0)
, _kbScroll(this, st::botKbScroll) , _kbScroll(this, st::botKbScroll)
, _keyboard() , _keyboard()
@ -3131,31 +3130,6 @@ void HistoryWidget::calcNextReplyReturn() {
if (!_replyReturn) updateControlsVisibility(); if (!_replyReturn) updateControlsVisibility();
} }
bool HistoryWidget::kbWasHidden() {
return _kbWasHidden;
}
void HistoryWidget::setKbWasHidden() {
if (_kbWasHidden || (!_keyboard.hasMarkup() && !_keyboard.forceReply())) return;
_kbWasHidden = true;
if (!_a_show.animating()) {
_kbScroll.hide();
_attachEmoji.show();
_kbHide.hide();
_cmdStart.hide();
_kbShow.show();
}
_field.setMaxHeight(st::maxFieldHeight);
_kbShown = false;
_kbReplyTo = 0;
if (!readyToForward() && (!_previewData || _previewData->pendingTill < 0) && !_replyToId) {
_replyForwardPreviewCancel.hide();
}
resizeEvent(0);
update();
}
void HistoryWidget::fastShowAtEnd(History *h) { void HistoryWidget::fastShowAtEnd(History *h) {
if (h == _history) { if (h == _history) {
h->getReadyFor(ShowAtTheEndMsgId, _fixedInScrollMsgId, _fixedInScrollMsgTop); h->getReadyFor(ShowAtTheEndMsgId, _fixedInScrollMsgId, _fixedInScrollMsgTop);
@ -3264,6 +3238,7 @@ void HistoryWidget::showHistory(const PeerId &peerId, MsgId showAtMsgId, bool re
_migrated->unreadBar->destroy(); _migrated->unreadBar->destroy();
} }
_history = _migrated = 0; _history = _migrated = 0;
updateBotKeyboard();
} }
if (_replyToId) { if (_replyToId) {
@ -3308,8 +3283,6 @@ void HistoryWidget::showHistory(const PeerId &peerId, MsgId showAtMsgId, bool re
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();
@ -4288,9 +4261,9 @@ void HistoryWidget::onBotStart() {
_peer->asUser()->botInfo->startToken = QString(); _peer->asUser()->botInfo->startToken = QString();
if (_keyboard.hasMarkup()) { if (_keyboard.hasMarkup()) {
if (_keyboard.singleUse() && _keyboard.forMsgId() == FullMsgId(_channel, _history->lastKeyboardId) && _history->lastKeyboardUsed) { if (_keyboard.singleUse() && _keyboard.forMsgId() == FullMsgId(_channel, _history->lastKeyboardId) && _history->lastKeyboardUsed) {
_kbWasHidden = true; _history->lastKeyboardHiddenId = _history->lastKeyboardId;
} }
if (!_kbWasHidden) _kbShown = _keyboard.hasMarkup(); if (!kbWasHidden()) _kbShown = _keyboard.hasMarkup();
} }
} }
updateControlsVisibility(); updateControlsVisibility();
@ -4872,6 +4845,10 @@ bool HistoryWidget::updateCmdStartShown() {
return false; return false;
} }
bool HistoryWidget::kbWasHidden() const {
return _history && (_keyboard.forMsgId() == FullMsgId(_history->channelId(), _history->lastKeyboardHiddenId));
}
void HistoryWidget::dropEvent(QDropEvent *e) { void HistoryWidget::dropEvent(QDropEvent *e) {
_attachDrag = DragStateNone; _attachDrag = DragStateNone;
updateDragAreas(); updateDragAreas();
@ -4927,7 +4904,9 @@ void HistoryWidget::onKbToggle(bool manual) {
_kbHide.hide(); _kbHide.hide();
if (_kbShown) { if (_kbShown) {
_kbShow.show(); _kbShow.show();
if (manual) _kbWasHidden = true; if (manual && _history) {
_history->lastKeyboardHiddenId = _keyboard.forMsgId().msg;
}
_kbScroll.hide(); _kbScroll.hide();
_kbShown = false; _kbShown = false;
@ -4959,7 +4938,9 @@ void HistoryWidget::onKbToggle(bool manual) {
_replyToText.setText(st::msgFont, _kbReplyTo->inDialogsText(), _textDlgOptions); _replyToText.setText(st::msgFont, _kbReplyTo->inDialogsText(), _textDlgOptions);
_replyForwardPreviewCancel.show(); _replyForwardPreviewCancel.show();
} }
if (manual) _kbWasHidden = false; if (manual && _history) {
_history->lastKeyboardHiddenId = 0;
}
} else { } else {
_kbHide.show(); _kbHide.show();
_kbShow.hide(); _kbShow.hide();
@ -4975,7 +4956,9 @@ void HistoryWidget::onKbToggle(bool manual) {
_replyToText.setText(st::msgFont, _kbReplyTo->inDialogsText(), _textDlgOptions); _replyToText.setText(st::msgFont, _kbReplyTo->inDialogsText(), _textDlgOptions);
_replyForwardPreviewCancel.show(); _replyForwardPreviewCancel.show();
} }
if (manual) _kbWasHidden = false; if (manual && _history) {
_history->lastKeyboardHiddenId = 0;
}
} }
resizeEvent(0); resizeEvent(0);
if (_kbHide.isHidden()) { if (_kbHide.isHidden()) {
@ -5903,8 +5886,10 @@ void HistoryWidget::updateBotKeyboard() {
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.hasMarkup() && _keyboard.forMsgId() == FullMsgId(_channel, _history->lastKeyboardId) && _history->lastKeyboardUsed) _kbWasHidden = true; if (_keyboard.singleUse() && _keyboard.hasMarkup() && _keyboard.forMsgId() == FullMsgId(_channel, _history->lastKeyboardId) && _history->lastKeyboardUsed) {
if (!isBotStart() && !isBlocked() && (wasVisible || _replyTo || (!_field.hasSendText() && !_kbWasHidden))) { _history->lastKeyboardHiddenId = _history->lastKeyboardId;
}
if (!isBotStart() && !isBlocked() && (wasVisible || _replyTo || (!_field.hasSendText() && !kbWasHidden()))) {
if (!_a_show.animating()) { if (!_a_show.animating()) {
if (hasMarkup) { if (hasMarkup) {
_kbScroll.show(); _kbScroll.show();

View File

@ -507,9 +507,6 @@ public:
void setReplyReturns(PeerId peer, const QList<MsgId> &replyReturns); void setReplyReturns(PeerId peer, const QList<MsgId> &replyReturns);
void calcNextReplyReturn(); void calcNextReplyReturn();
bool kbWasHidden();
void setKbWasHidden();
void updatePreview(); void updatePreview();
void previewCancel(); void previewCancel();
@ -770,7 +767,9 @@ private:
anim::cvalue a_recordCancel; anim::cvalue a_recordCancel;
int32 _recordCancelWidth; int32 _recordCancelWidth;
bool _kbShown, _kbWasHidden; bool kbWasHidden() const;
bool _kbShown;
HistoryItem *_kbReplyTo; HistoryItem *_kbReplyTo;
ScrollArea _kbScroll; ScrollArea _kbScroll;
BotKeyboard _keyboard; BotKeyboard _keyboard;

View File

@ -2411,7 +2411,7 @@ void MainWidget::showMediaOverview(PeerData *peer, MediaOverviewType type, bool
_peerInStack = history.peer(); _peerInStack = history.peer();
_msgIdInStack = history.msgId(); _msgIdInStack = history.msgId();
dlgUpdated(); dlgUpdated();
_stack.push_back(new StackItemHistory(_peerInStack, _msgIdInStack, history.replyReturns(), history.kbWasHidden())); _stack.push_back(new StackItemHistory(_peerInStack, _msgIdInStack, history.replyReturns()));
} }
} }
if (overview) { if (overview) {
@ -2467,7 +2467,7 @@ void MainWidget::showPeerProfile(PeerData *peer, bool back, int32 lastScrollTop)
_peerInStack = history.peer(); _peerInStack = history.peer();
_msgIdInStack = history.msgId(); _msgIdInStack = history.msgId();
dlgUpdated(); dlgUpdated();
_stack.push_back(new StackItemHistory(_peerInStack, _msgIdInStack, history.replyReturns(), history.kbWasHidden())); _stack.push_back(new StackItemHistory(_peerInStack, _msgIdInStack, history.replyReturns()));
} }
} }
if (overview) { if (overview) {
@ -2521,7 +2521,6 @@ void MainWidget::showBackFromStack() {
StackItemHistory *histItem = static_cast<StackItemHistory*>(item); StackItemHistory *histItem = static_cast<StackItemHistory*>(item);
showPeerHistory(histItem->peer->id, App::main()->activeMsgId(), true); showPeerHistory(histItem->peer->id, App::main()->activeMsgId(), true);
history.setReplyReturns(histItem->peer->id, histItem->replyReturns); history.setReplyReturns(histItem->peer->id, histItem->replyReturns);
if (histItem->kbWasHidden) history.setKbWasHidden();
} else if (item->type() == ProfileStackItem) { } else if (item->type() == ProfileStackItem) {
StackItemProfile *profItem = static_cast<StackItemProfile*>(item); StackItemProfile *profItem = static_cast<StackItemProfile*>(item);
showPeerProfile(profItem->peer, true, profItem->lastScrollTop); showPeerProfile(profItem->peer, true, profItem->lastScrollTop);

View File

@ -126,15 +126,14 @@ public:
class StackItemHistory : public StackItem { class StackItemHistory : public StackItem {
public: public:
StackItemHistory(PeerData *peer, MsgId msgId, QList<MsgId> replyReturns, bool kbWasHidden) : StackItem(peer), StackItemHistory(PeerData *peer, MsgId msgId, QList<MsgId> replyReturns) : StackItem(peer),
msgId(msgId), replyReturns(replyReturns), kbWasHidden(kbWasHidden) { msgId(msgId), replyReturns(replyReturns) {
} }
StackItemType type() const { StackItemType type() const {
return HistoryStackItem; return HistoryStackItem;
} }
MsgId msgId; MsgId msgId;
QList<MsgId> replyReturns; QList<MsgId> replyReturns;
bool kbWasHidden;
}; };
class StackItemProfile : public StackItem { class StackItemProfile : public StackItem {

View File

@ -914,9 +914,6 @@
<ClInclude Include="SourceFiles\mtproto\mtpAuthKey.h"> <ClInclude Include="SourceFiles\mtproto\mtpAuthKey.h">
<Filter>mtproto</Filter> <Filter>mtproto</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="SourceFiles\config.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="SourceFiles\logs.h"> <ClInclude Include="SourceFiles\logs.h">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClInclude> </ClInclude>
@ -989,6 +986,9 @@
<ClInclude Include="SourceFiles\numbers.h"> <ClInclude Include="SourceFiles\numbers.h">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="SourceFiles\config.h">
<Filter>Version</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<CustomBuild Include="SourceFiles\mtproto\mtpConnection.h"> <CustomBuild Include="SourceFiles\mtproto\mtpConnection.h">