version 0.8.2.dev ready

This commit is contained in:
John Preston 2015-04-08 02:03:32 +03:00
parent fb2c140fad
commit 70f3568e16
25 changed files with 326 additions and 190 deletions

View File

@ -1,9 +1,9 @@
@echo OFF
set "AppVersion=8001"
set "AppVersionStrSmall=0.8.1"
set "AppVersionStr=0.8.1"
set "AppVersionStrFull=0.8.1.0"
set "AppVersion=8002"
set "AppVersionStrSmall=0.8.2"
set "AppVersionStr=0.8.2"
set "AppVersionStrFull=0.8.2.0"
set "DevChannel=1"
if %DevChannel% neq 0 goto preparedev

View File

@ -984,7 +984,7 @@ btnAttachEmoji: iconedButton(btnAttachDocument) {
width: 32px;
}
replySkip: 52px;
replySkip: 51px;
replyColor: #377aae;
replyHeight: 49px;
replyTop: 8px;

View File

@ -262,7 +262,7 @@ void ApiWrap::gotWebPages(const MTPmessages_Messages &msgs, mtpRequestId req) {
}
const WebPageItems &items(App::webPageItems());
for (WebPagesPending::iterator i = _webPagesPending.begin(); i != _webPagesPending.cend(); ++i) {
for (WebPagesPending::iterator i = _webPagesPending.begin(); i != _webPagesPending.cend();) {
if (i.value() == req) {
if (i.key()->pendingTill > 0) {
i.key()->pendingTill = -1;

View File

@ -747,19 +747,6 @@ namespace App {
}
}
void feedMessageMedia(MsgId msgId, const MTPMessage &msg) {
const MTPMessageMedia *media = 0;
switch (msg.type()) {
case mtpc_message: media = &msg.c_message().vmedia; break;
}
if (media) {
MsgsData::iterator i = msgsData.find(msgId);
if (i != msgsData.cend()) {
i.value()->updateMedia(*media);
}
}
}
PhotoData *feedPhoto(const MTPPhoto &photo, PhotoData *convert) {
switch (photo.type()) {
case mtpc_photo: {
@ -906,7 +893,7 @@ namespace App {
}
WebPageData *feedWebPage(const MTPDwebPage &webpage, WebPageData *convert) {
return App::webPage(webpage.vid.v, convert, webpage.has_type() ? qs(webpage.vtype) : qsl("article"), qs(webpage.vurl), qs(webpage.vdisplay_url), webpage.has_site_name() ? qs(webpage.vsite_name) : QString(), webpage.has_title() ? qs(webpage.vtitle) : QString(), webpage.has_description() ? qs(webpage.vdescription) : QString(), webpage.has_photo() ? App::feedPhoto(webpage.vphoto) : 0, webpage.has_duration() ? webpage.vduration.v : 0, webpage.has_author() ? qs(webpage.vauthor) : QString());
return App::webPage(webpage.vid.v, convert, webpage.has_type() ? qs(webpage.vtype) : qsl("article"), qs(webpage.vurl), qs(webpage.vdisplay_url), webpage.has_site_name() ? qs(webpage.vsite_name) : QString(), webpage.has_title() ? qs(webpage.vtitle) : QString(), webpage.has_description() ? qs(webpage.vdescription) : QString(), webpage.has_photo() ? App::feedPhoto(webpage.vphoto) : 0, webpage.has_duration() ? webpage.vduration.v : 0, webpage.has_author() ? qs(webpage.vauthor) : QString(), 0);
}
WebPageData *feedWebPage(const MTPDwebPagePending &webpage, WebPageData *convert) {
@ -1211,7 +1198,7 @@ namespace App {
}
convert->id = webPage;
}
if ((convert->url.isEmpty() && !url.isEmpty()) || (convert->pendingTill && convert->pendingTill != pendingTill)) {
if ((convert->url.isEmpty() && !url.isEmpty()) || (convert->pendingTill && convert->pendingTill != pendingTill && pendingTill >= -1)) {
convert->type = toWebPageType(type);
convert->url = url;
convert->displayUrl = displayUrl;
@ -1223,15 +1210,7 @@ namespace App {
convert->author = author;
if (convert->pendingTill > 0 && pendingTill <= 0 && api()) api()->clearWebPageRequest(convert);
convert->pendingTill = pendingTill;
MainWidget *m = App::main();
WebPageItems::const_iterator j = ::webPageItems.constFind(convert);
if (j != ::webPageItems.cend()) {
for (HistoryItemsMap::const_iterator k = j.value().cbegin(), e = j.value().cend(); k != e; ++k) {
k.key()->initDimensions();
if (m) m->itemResized(k.key());
}
}
if (App::main()) App::main()->webPageUpdated(convert);
}
}
WebPagesData::const_iterator i = webPagesData.constFind(webPage);
@ -1240,7 +1219,7 @@ namespace App {
if (convert) {
result = convert;
} else {
result = new WebPageData(webPage, toWebPageType(type), url, displayUrl, siteName, title, description, photo, duration, author, pendingTill);
result = new WebPageData(webPage, toWebPageType(type), url, displayUrl, siteName, title, description, photo, duration, author, (pendingTill >= -1) ? pendingTill : -1);
if (pendingTill > 0 && api()) {
api()->requestWebPageDelayed(result);
}
@ -1249,7 +1228,7 @@ namespace App {
} else {
result = i.value();
if (result != convert) {
if ((result->url.isEmpty() && !url.isEmpty()) || (result->pendingTill && result->pendingTill != pendingTill)) {
if ((result->url.isEmpty() && !url.isEmpty()) || (result->pendingTill && result->pendingTill != pendingTill && pendingTill >= -1)) {
result->type = toWebPageType(type);
result->url = url;
result->displayUrl = displayUrl;
@ -1261,15 +1240,7 @@ namespace App {
result->author = author;
if (result->pendingTill > 0 && pendingTill <= 0 && api()) api()->clearWebPageRequest(result);
result->pendingTill = pendingTill;
MainWidget *m = App::main();
WebPageItems::const_iterator j = ::webPageItems.constFind(result);
if (j != ::webPageItems.cend()) {
for (HistoryItemsMap::const_iterator k = j.value().cbegin(), e = j.value().cend(); k != e; ++k) {
k.key()->initDimensions();
if (m) m->itemResized(k.key());
}
}
if (App::main()) App::main()->webPageUpdated(result);
}
}
}

View File

@ -84,7 +84,6 @@ namespace App {
void feedWereDeleted(const QVector<MTPint> &msgsIds);
void feedUserLinks(const MTPVector<MTPcontacts_Link> &links);
void feedUserLink(MTPint userId, const MTPContactLink &myLink, const MTPContactLink &foreignLink);
void feedMessageMedia(MsgId msgId, const MTPMessage &msg);
int32 maxMsgId();
ImagePtr image(const MTPPhotoSize &size);
@ -119,7 +118,7 @@ namespace App {
VideoData *video(const VideoId &video, VideoData *convert = 0, const uint64 &access = 0, int32 user = 0, int32 date = 0, int32 duration = 0, int32 w = 0, int32 h = 0, const ImagePtr &thumb = ImagePtr(), int32 dc = 0, int32 size = 0);
AudioData *audio(const AudioId &audio, AudioData *convert = 0, const uint64 &access = 0, int32 user = 0, int32 date = 0, const QString &mime = QString(), int32 duration = 0, int32 dc = 0, int32 size = 0);
DocumentData *document(const DocumentId &document, DocumentData *convert = 0, const uint64 &access = 0, int32 date = 0, const QVector<MTPDocumentAttribute> &attributes = QVector<MTPDocumentAttribute>(), const QString &mime = QString(), const ImagePtr &thumb = ImagePtr(), int32 dc = 0, int32 size = 0);
WebPageData *webPage(const WebPageId &webPage, WebPageData *convert = 0, const QString &type = QString(), const QString &url = QString(), const QString &displayUrl = QString(), const QString &siteName = QString(), const QString &title = QString(), const QString &description = QString(), PhotoData *photo = 0, int32 duration = 0, const QString &author = QString(), int32 pendingTill = 0);
WebPageData *webPage(const WebPageId &webPage, WebPageData *convert = 0, const QString &type = QString(), const QString &url = QString(), const QString &displayUrl = QString(), const QString &siteName = QString(), const QString &title = QString(), const QString &description = QString(), PhotoData *photo = 0, int32 duration = 0, const QString &author = QString(), int32 pendingTill = -2);
ImageLinkData *imageLink(const QString &imageLink, ImageLinkType type = InvalidImageLink, const QString &url = QString());
void forgetMedia();

View File

@ -654,9 +654,9 @@ void Application::checkMapVersion() {
psRegisterCustomScheme();
if (Local::oldMapVersion()) {
QString versionFeatures;
if (DevChannel && Local::oldMapVersion() < 8001) {
versionFeatures = QString::fromUtf8("\xe2\x80\x94 Link previews for Twitter, YouTube, Instagram and certain other links\n\xe2\x80\x94 Two-step verification\n\xe2\x80\x94 View all your Telegram sessions, terminate specific sessions\n\xe2\x80\x94 Text is pasted from clipboard when clipboard has both text and image and image sending was cancelled").replace('@', qsl("@") + QChar(0x200D));
} else if (!DevChannel && Local::oldMapVersion() < 8002) {
if (DevChannel && Local::oldMapVersion() < 8002) {
versionFeatures = QString::fromUtf8("\xe2\x80\x94 Link previews bugfixes\n\xe2\x80\x94 Links in preview descriptions are now clickable\n\xe2\x80\x94 Twitter and Instagram mentions and hashtags in previews are clickable\n\xe2\x80\x94 Fixed file uploading\n\xe2\x80\x94 Fixed photo, document and sticker forwarding").replace('@', qsl("@") + QChar(0x200D));
} else if (!DevChannel && Local::oldMapVersion() < 8003) {
versionFeatures = lang(lng_new_version_text).trimmed();
}
if (!versionFeatures.isEmpty()) {

View File

@ -459,7 +459,7 @@ bool PasscodeBox::recoverStartFail(const RPCError &error) {
}
RecoverBox::RecoverBox(const QString &pattern) :
_submitRequest(0), _pattern(lng_signin_recover_hint(lt_recover_email, pattern)),
_submitRequest(0), _pattern(st::usernameFont->m.elidedText(lng_signin_recover_hint(lt_recover_email, pattern), Qt::ElideRight, st::boxWidth - st::addContactPadding.left() - st::addContactPadding.right())),
_saveButton(this, lang(lng_passcode_submit), st::btnSelectDone),
_cancelButton(this, lang(lng_cancel), st::btnSelectCancel),
_recoverCode(this, st::inpAddContact, lang(lng_signin_code)) {
@ -509,7 +509,7 @@ void RecoverBox::paintEvent(QPaintEvent *e) {
p.setFont(st::usernameFont->f);
int32 w = width() - st::addContactPadding.left() - st::addContactPadding.right();
p.drawText(QRect(st::addContactPadding.left(), _recoverCode.y() - st::usernameSkip - st::addContactPadding.top(), w, st::addContactPadding.top() + st::usernameSkip), st::usernameFont->m.elidedText(_pattern, Qt::ElideRight, w), style::al_center);
p.drawText(QRect(st::addContactPadding.left(), _recoverCode.y() - st::usernameSkip - st::addContactPadding.top(), w, st::addContactPadding.top() + st::usernameSkip), _pattern, style::al_center);
if (!_error.isEmpty()) {
p.setPen(st::setErrColor->p);

View File

@ -17,8 +17,8 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
*/
#pragma once
static const int32 AppVersion = 8001;
static const wchar_t *AppVersionStr = L"0.8.1";
static const int32 AppVersion = 8002;
static const wchar_t *AppVersionStr = L"0.8.2";
static const bool DevChannel = true;
static const wchar_t *AppNameOld = L"Telegram Win (Unofficial)";

View File

@ -40,7 +40,7 @@ inline bool emojiEdge(const QChar *ch) {
inline QString replaceEmojis(const QString &text) {
QString result;
LinkRanges lnkRanges = textParseLinks(text);
LinkRanges lnkRanges = textParseLinks(text, TextParseLinks | TextParseMentions | TextParseHashtags);
int32 currentLink = 0, lnkCount = lnkRanges.size();
const QChar *emojiStart = text.unicode(), *emojiEnd = emojiStart, *e = text.cend();
bool canFindEmoji = true, consumePrevious = false;

View File

@ -42,15 +42,13 @@ namespace {
FlatInputStyle _flatInputStyle;
}
FlatInput::FlatInput(QWidget *parent, const style::flatInput &st, const QString &pholder, const QString &v) : QLineEdit(v, parent), _oldtext(v), _kev(0), _customUpDown(false), _phVisible(!v.length()),
FlatInput::FlatInput(QWidget *parent, const style::flatInput &st, const QString &pholder, const QString &v) : QLineEdit(v, parent), _fullph(pholder), _oldtext(v), _kev(0), _customUpDown(false), _phVisible(!v.length()),
a_phLeft(_phVisible ? 0 : st.phShift), a_phAlpha(_phVisible ? 1 : 0), a_phColor(st.phColor->c),
a_borderColor(st.borderColor->c), a_bgColor(st.bgColor->c), _notingBene(0), _st(st) {
resize(_st.width, _st.height);
setFont(_st.font->f);
setAlignment(_st.align);
_ph = _st.font->m.elidedText(pholder, Qt::ElideRight, width() - _st.textMrg.left() - _st.textMrg.right() - _st.phPos.x() - 1);
QPalette p(palette());
p.setColor(QPalette::Text, _st.textColor->c);
@ -184,6 +182,15 @@ void FlatInput::focusOutEvent(QFocusEvent *e) {
emit blurred();
}
void FlatInput::resizeEvent(QResizeEvent *e) {
int32 availw = width() - _st.textMrg.left() - _st.textMrg.right() - _st.phPos.x() - 1;
if (_st.font->m.width(_fullph) > availw) {
_ph = _st.font->m.elidedText(_fullph, Qt::ElideRight, availw);
} else {
_ph = _fullph;
}
}
QSize FlatInput::sizeHint() const {
return geometry().size();
}

View File

@ -34,6 +34,7 @@ public:
void focusInEvent(QFocusEvent *e);
void focusOutEvent(QFocusEvent *e);
void keyPressEvent(QKeyEvent *e);
void resizeEvent(QResizeEvent *e);
void notaBene();
@ -69,7 +70,7 @@ protected:
private:
QString _ph, _oldtext;
QString _ph, _fullph, _oldtext;
QKeyEvent *_kev;
bool _customUpDown;

View File

@ -547,7 +547,7 @@ public:
end = start + src.size();
if (options.flags & TextParseLinks) {
lnkRanges = textParseLinks(src, rich);
lnkRanges = textParseLinks(src, options.flags, rich);
}
while (start != end && chIsTrimmed(*start, rich)) {
@ -593,9 +593,21 @@ public:
const TextLinkData &data(links[lnkIndex - maxLnkIndex - 1]);
TextLinkPtr lnk;
if (data.fullDisplayed < -2) { // mention
lnk = TextLinkPtr(new MentionLink(data.url));
if (options.flags & TextTwitterMentions) {
lnk = TextLinkPtr(new TextLink(qsl("https://twitter.com/") + data.url.mid(1), true));
} else if (options.flags & TextInstagramMentions) {
lnk = TextLinkPtr(new TextLink(qsl("https://instagram.com/") + data.url.mid(1) + '/', true));
} else {
lnk = TextLinkPtr(new MentionLink(data.url));
}
} else if (data.fullDisplayed < -1) { // hashtag
lnk = TextLinkPtr(new HashtagLink(data.url));
if (options.flags & TextTwitterMentions) {
lnk = TextLinkPtr(new TextLink(qsl("https://twitter.com/hashtag/") + data.url.mid(1) + qsl("?src=hash"), true));
} else if (options.flags & TextInstagramMentions) {
lnk = TextLinkPtr(new TextLink(qsl("https://instagram.com/explore/tags/") + data.url.mid(1) + '/', true));
} else {
lnk = TextLinkPtr(new HashtagLink(data.url));
}
} else if (data.fullDisplayed < 0) { // email
lnk = TextLinkPtr(new EmailLink(data.url));
} else {
@ -3993,7 +4005,7 @@ QString textSearchKey(const QString &text) {
bool textSplit(QString &sendingText, QString &leftText, int32 limit) {
if (leftText.isEmpty() || !limit) return false;
LinkRanges lnkRanges = textParseLinks(leftText);
LinkRanges lnkRanges = textParseLinks(leftText, TextParseLinks | TextParseMentions | TextParseHashtags);
int32 currentLink = 0, lnkCount = lnkRanges.size();
int32 s = 0, half = limit / 2, goodLevel = 0;
@ -4070,9 +4082,11 @@ bool textSplit(QString &sendingText, QString &leftText, int32 limit) {
return true;
}
LinkRanges textParseLinks(const QString &text, bool rich) { // some code is duplicated in flattextarea.cpp!
LinkRanges textParseLinks(const QString &text, int32 flags, bool rich) { // some code is duplicated in flattextarea.cpp!
LinkRanges lnkRanges;
bool withHashtags = (flags & TextParseHashtags), withMentions = (flags & TextParseMentions);
initLinkSets();
int32 len = text.size(), nextCmd = rich ? 0 : len;
const QChar *start = text.unicode(), *end = start + text.size();
@ -4086,8 +4100,8 @@ LinkRanges textParseLinks(const QString &text, bool rich) { // some code is dupl
}
QRegularExpressionMatch mDomain = _reDomain.match(text, matchOffset);
QRegularExpressionMatch mExplicitDomain = _reExplicitDomain.match(text, matchOffset);
QRegularExpressionMatch mHashtag = _reHashtag.match(text, matchOffset);
QRegularExpressionMatch mMention = _reMention.match(text, matchOffset);
QRegularExpressionMatch mHashtag = withHashtags ? _reHashtag.match(text, matchOffset) : QRegularExpressionMatch();
QRegularExpressionMatch mMention = withMentions ? _reMention.match(text, matchOffset) : QRegularExpressionMatch();
if (!mDomain.hasMatch() && !mExplicitDomain.hasMatch() && !mHashtag.hasMatch() && !mMention.hasMatch()) break;
LinkRange link;

View File

@ -25,6 +25,19 @@ QString textAccentFold(const QString &text);
QString textSearchKey(const QString &text);
bool textSplit(QString &sendingText, QString &leftText, int32 limit);
enum {
TextParseMultiline = 0x001,
TextParseLinks = 0x002,
TextParseRichText = 0x004,
TextParseMentions = 0x008,
TextParseHashtags = 0x010,
TextTwitterMentions = 0x020,
TextTwitterHashtags = 0x040,
TextInstagramMentions = 0x080,
TextInstagramHashtags = 0x100,
};
struct LinkRange {
LinkRange() : from(0), len(0) {
}
@ -32,7 +45,7 @@ struct LinkRange {
int32 len;
};
typedef QVector<LinkRange> LinkRanges;
LinkRanges textParseLinks(const QString &text, bool rich = false);
LinkRanges textParseLinks(const QString &text, int32 flags, bool rich = false);
#include "gui/emoji_config.h"
@ -387,12 +400,6 @@ enum TextCommands {
TextCommandLangTag = 0x20,
};
enum {
TextParseMultiline = 0x01,
TextParseLinks = 0x02,
TextParseRichText = 0x04,
};
struct TextParseOptions {
int32 flags;
int32 maxw;

View File

@ -44,13 +44,13 @@ TextParseOptions _textDlgOptions = {
namespace {
TextParseOptions _historyTextOptions = {
TextParseLinks | TextParseMultiline | TextParseRichText, // flags
TextParseLinks | TextParseMentions | TextParseHashtags | TextParseMultiline | TextParseRichText, // flags
0, // maxw
0, // maxh
Qt::LayoutDirectionAuto, // dir
};
TextParseOptions _historySrvOptions = {
TextParseLinks | TextParseMultiline | TextParseRichText, // flags
TextParseLinks | TextParseMentions | TextParseHashtags | TextParseMultiline | TextParseRichText, // flags
0, // maxw
0, // maxh
Qt::LayoutDirectionAuto, // lang-dependent
@ -62,7 +62,19 @@ namespace {
Qt::LayoutDirectionAuto, // dir
};
TextParseOptions _webpageDescriptionOptions = {
/*TextParseLinks | */TextParseMultiline | TextParseRichText, // flags
TextParseLinks | TextParseMultiline | TextParseRichText, // flags
0, // maxw
0, // maxh
Qt::LayoutDirectionAuto, // dir
};
TextParseOptions _twitterDescriptionOptions = {
TextParseLinks | TextParseMentions | TextTwitterMentions | TextParseHashtags | TextTwitterHashtags | TextParseMultiline | TextParseRichText, // flags
0, // maxw
0, // maxh
Qt::LayoutDirectionAuto, // dir
};
TextParseOptions _instagramDescriptionOptions = {
TextParseLinks | TextParseMentions | TextInstagramMentions | TextParseHashtags | TextInstagramHashtags | TextParseMultiline | TextParseRichText, // flags
0, // maxw
0, // maxh
Qt::LayoutDirectionAuto, // dir
@ -718,7 +730,17 @@ HistoryItem *History::createItem(HistoryBlock *block, const MTPmessage &msg, boo
} break;
}
return regItem(result, returnExisting);
HistoryItem *existing = regItem(result, true);
if (existing && result != existing) {
const MTPMessageMedia *media = 0;
switch (msg.type()) {
case mtpc_message: media = &msg.c_message().vmedia; break;
}
if (media) {
existing->updateMedia(*media);
}
}
return (returnExisting || existing == result) ? existing : 0;
}
HistoryItem *History::createItemForwarded(HistoryBlock *block, MsgId id, HistoryMessage *msg) {
@ -1710,8 +1732,10 @@ bool HistoryPhoto::hasPoint(int32 x, int32 y, const HistoryItem *parent, int32 w
return (x >= 0 && y >= 0 && x < width && y < _height);
}
TextLinkPtr HistoryPhoto::getLink(int32 x, int32 y, const HistoryItem *parent, int32 width) const {
void HistoryPhoto::getState(TextLinkPtr &lnk, bool &inText, int32 x, int32 y, const HistoryItem *parent, int32 width) const {
if (width < 0) width = w;
if (width < 1) return;
int skipx = 0, skipy = 0, height = _height;
if (const HistoryReply *reply = toHistoryReply(parent)) {
skipx = st::mediaPadding.left();
@ -1722,18 +1746,20 @@ TextLinkPtr HistoryPhoto::getLink(int32 x, int32 y, const HistoryItem *parent, i
replyFrom = st::msgPadding.top() + st::msgNameFont->height;
skipy += replyFrom;
if (x >= st::mediaPadding.left() && y >= st::msgPadding.top() && x < width - st::mediaPadding.left() - st::mediaPadding.right() && x < st::mediaPadding.left() + parent->from()->nameText.maxWidth() && y < replyFrom) {
return parent->from()->lnk;
lnk = parent->from()->lnk;
return;
}
}
if (x >= 0 && y >= replyFrom + st::msgReplyPadding.top() && x < width && y < skipy - st::msgReplyPadding.bottom() - st::mediaPadding.top()) {
return reply->replyToLink();
lnk = reply->replyToLink();
return;
}
width -= st::mediaPadding.left() + st::mediaPadding.right();
}
if (x >= skipx && y >= skipy && x < skipx + width && y < height) {
return openl;
lnk = openl;
return;
}
return TextLinkPtr();
}
HistoryMedia *HistoryPhoto::clone() const {
@ -1984,9 +2010,9 @@ bool HistoryVideo::hasPoint(int32 x, int32 y, const HistoryItem *parent, int32 w
return (x >= 0 && y >= 0 && x < width && y < _height);
}
TextLinkPtr HistoryVideo::getLink(int32 x, int32 y, const HistoryItem *parent, int32 width) const {
void HistoryVideo::getState(TextLinkPtr &lnk, bool &inText, int32 x, int32 y, const HistoryItem *parent, int32 width) const {
if (width < 0) width = w;
if (width < 1) return TextLinkPtr();
if (width < 1) return;
const HistoryReply *reply = toHistoryReply(parent);
int skipy = 0, replyFrom = 0;
@ -2006,7 +2032,8 @@ TextLinkPtr HistoryVideo::getLink(int32 x, int32 y, const HistoryItem *parent, i
if (!out) { // draw Download / Save As button
int32 btnw = _buttonWidth, btnh = st::mediaSaveButton.height, btnx = width - _buttonWidth, btny = skipy + (_height - skipy - btnh) / 2;
if (x >= btnx && y >= btny && x < btnx + btnw && y < btny + btnh) {
return data->loader ? _cancell : _savel;
lnk = data->loader ? _cancell : _savel;
return;
}
width -= btnw + st::mediaSaveDelta;
}
@ -2014,18 +2041,20 @@ TextLinkPtr HistoryVideo::getLink(int32 x, int32 y, const HistoryItem *parent, i
if (reply) {
if (!parent->out() && parent->history()->peer->chat) {
if (x >= st::mediaPadding.left() && y >= st::msgPadding.top() && x < width - st::mediaPadding.left() - st::mediaPadding.right() && x < st::mediaPadding.left() + parent->from()->nameText.maxWidth() && y < replyFrom) {
return parent->from()->lnk;
lnk = parent->from()->lnk;
return;
}
}
if (x >= 0 && y >= replyFrom + st::msgReplyPadding.top() && x < width && y < skipy - st::msgReplyPadding.bottom()) {
return reply->replyToLink();
lnk = reply->replyToLink();
return;
}
}
if (x >= 0 && y >= skipy && x < width && y < _height && !data->loader && data->access) {
return _openl;
lnk = _openl;
return;
}
return TextLinkPtr();
}
HistoryMedia *HistoryVideo::clone() const {
@ -2367,9 +2396,9 @@ bool HistoryAudio::hasPoint(int32 x, int32 y, const HistoryItem *parent, int32 w
return (x >= 0 && y >= 0 && x < width && y < _height);
}
TextLinkPtr HistoryAudio::getLink(int32 x, int32 y, const HistoryItem *parent, int32 width) const {
void HistoryAudio::getState(TextLinkPtr &lnk, bool &inText, int32 x, int32 y, const HistoryItem *parent, int32 width) const {
if (width < 0) width = w;
if (width < 1) return TextLinkPtr();
if (width < 1) return;
const HistoryReply *reply = toHistoryReply(parent);
int skipy = 0, replyFrom = 0;
@ -2389,7 +2418,8 @@ TextLinkPtr HistoryAudio::getLink(int32 x, int32 y, const HistoryItem *parent, i
if (!out) { // draw Download / Save As button
int32 btnw = _buttonWidth, btnh = st::mediaSaveButton.height, btnx = width - _buttonWidth, btny = skipy + (_height - skipy - btnh) / 2;
if (x >= btnx && y >= btny && x < btnx + btnw && y < btny + btnh) {
return data->loader ? _cancell : _savel;
lnk = data->loader ? _cancell : _savel;
return;
}
width -= btnw + st::mediaSaveDelta;
}
@ -2397,18 +2427,20 @@ TextLinkPtr HistoryAudio::getLink(int32 x, int32 y, const HistoryItem *parent, i
if (reply) {
if (!parent->out() && parent->history()->peer->chat) {
if (x >= st::mediaPadding.left() && y >= st::msgPadding.top() && x < width - st::mediaPadding.left() - st::mediaPadding.right() && x < st::mediaPadding.left() + parent->from()->nameText.maxWidth() && y < replyFrom) {
return parent->from()->lnk;
lnk = parent->from()->lnk;
return;
}
}
if (x >= 0 && y >= replyFrom + st::msgReplyPadding.top() && x < width && y < skipy - st::msgReplyPadding.bottom()) {
return reply->replyToLink();
lnk = reply->replyToLink();
return;
}
}
if (x >= 0 && y >= skipy && x < width && y < _height && !data->loader && data->access) {
return _openl;
lnk = _openl;
return;
}
return TextLinkPtr();
}
HistoryMedia *HistoryAudio::clone() const {
@ -2689,9 +2721,9 @@ int32 HistoryDocument::countHeight(const HistoryItem *parent, int32 width) const
return _height;
}
TextLinkPtr HistoryDocument::getLink(int32 x, int32 y, const HistoryItem *parent, int32 width) const {
void HistoryDocument::getState(TextLinkPtr &lnk, bool &inText, int32 x, int32 y, const HistoryItem *parent, int32 width) const {
if (width < 0) width = w;
if (width < 1) return TextLinkPtr();
if (width < 1) return;
bool out = parent->out(), hovered, pressed;
if (width >= _maxw) {
@ -2700,7 +2732,8 @@ TextLinkPtr HistoryDocument::getLink(int32 x, int32 y, const HistoryItem *parent
if (parent == animated.msg) {
int32 h = (width == w) ? _height : (width * animated.h / animated.w);
if (h < 1) h = 1;
return (x >= 0 && y >= 0 && x < width && y < h) ? _openl : TextLinkPtr();
lnk = (x >= 0 && y >= 0 && x < width && y < h) ? _openl : TextLinkPtr();
return;
}
const HistoryReply *reply = toHistoryReply(parent);
@ -2716,7 +2749,8 @@ TextLinkPtr HistoryDocument::getLink(int32 x, int32 y, const HistoryItem *parent
if (!out) { // draw Download / Save As button
int32 btnw = _buttonWidth, btnh = st::mediaSaveButton.height, btnx = width - _buttonWidth, btny = skipy + (_height - skipy - btnh) / 2;
if (x >= btnx && y >= btny && x < btnx + btnw && y < btny + btnh) {
return data->loader ? _cancell : _savel;
lnk = data->loader ? _cancell : _savel;
return;
}
width -= btnw + st::mediaSaveDelta;
}
@ -2724,18 +2758,20 @@ TextLinkPtr HistoryDocument::getLink(int32 x, int32 y, const HistoryItem *parent
if (reply) {
if (!parent->out() && parent->history()->peer->chat) {
if (x >= st::mediaPadding.left() && y >= st::msgPadding.top() && x < width - st::mediaPadding.left() - st::mediaPadding.right() && x < st::mediaPadding.left() + parent->from()->nameText.maxWidth() && y < replyFrom) {
return parent->from()->lnk;
lnk = parent->from()->lnk;
return;
}
}
if (x >= 0 && y >= replyFrom + st::msgReplyPadding.top() && x < width && y < skipy - st::msgReplyPadding.bottom()) {
return reply->replyToLink();
lnk = reply->replyToLink();
return;
}
}
if (x >= 0 && y >= skipy && x < width && y < _height && !data->loader && data->access) {
return _openl;
lnk = _openl;
return;
}
return TextLinkPtr();
}
HistoryMedia *HistoryDocument::clone() const {
@ -2926,9 +2962,10 @@ int32 HistorySticker::countHeight(const HistoryItem *parent, int32 width) const
return _minh;
}
TextLinkPtr HistorySticker::getLink(int32 x, int32 y, const HistoryItem *parent, int32 width) const {
void HistorySticker::getState(TextLinkPtr &lnk, bool &inText, int32 x, int32 y, const HistoryItem *parent, int32 width) const {
if (width < 0) width = w;
if (width < 1) return TextLinkPtr();
if (width < 1) return;
if (width > _maxw) width = _maxw;
int32 usew = _maxw, usex = 0;
@ -2938,10 +2975,10 @@ TextLinkPtr HistorySticker::getLink(int32 x, int32 y, const HistoryItem *parent,
int32 rw = width - usew, rh = st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom();
int32 rx = parent->out() ? 0 : usew, ry = _height - rh;
if (x >= rx && y >= ry && x < rx + rw && y < ry + rh) {
return reply->replyToLink();
lnk = reply->replyToLink();
return;
}
}
return TextLinkPtr();
}
HistoryMedia *HistorySticker::clone() const {
@ -3002,7 +3039,7 @@ bool HistoryContact::hasPoint(int32 x, int32 y, const HistoryItem *parent, int32
return (x >= 0 && y <= 0 && x < w && y < _height);
}
TextLinkPtr HistoryContact::getLink(int32 x, int32 y, const HistoryItem *parent, int32 width) const {
void HistoryContact::getState(TextLinkPtr &lnk, bool &inText, int32 x, int32 y, const HistoryItem *parent, int32 width) const {
if (width < 0) width = w;
const HistoryReply *reply = toHistoryReply(parent);
@ -3018,18 +3055,20 @@ TextLinkPtr HistoryContact::getLink(int32 x, int32 y, const HistoryItem *parent,
if (reply) {
if (!parent->out() && parent->history()->peer->chat) {
if (x >= st::mediaPadding.left() && y >= st::msgPadding.top() && x < width - st::mediaPadding.left() - st::mediaPadding.right() && x < st::mediaPadding.left() + parent->from()->nameText.maxWidth() && y < replyFrom) {
return parent->from()->lnk;
lnk = parent->from()->lnk;
return;
}
}
if (x >= 0 && y >= replyFrom + st::msgReplyPadding.top() && x < width && y < skipy - st::msgReplyPadding.bottom()) {
return reply->replyToLink();
lnk = reply->replyToLink();
return;
}
}
if (x >= 0 && y >= skipy && x < w && y < _height && contact) {
return contact->lnk;
lnk = contact->lnk;
return;
}
return TextLinkPtr();
}
HistoryMedia *HistoryContact::clone() const {
@ -3214,16 +3253,22 @@ void HistoryWebPage::initDimensions(const HistoryItem *parent) {
_maxw = qMax(_maxw, int32(st::webPageLeft + _title.maxWidth() + st::webPagePhotoDelta + st::webPagePhotoSize));
} else {
_maxw = qMax(_maxw, int32(st::webPageLeft + _title.maxWidth() + parent->timeWidth()));
_minh += st::webPageTitleFont->height;
_minh += qMin(_title.minHeight(), 2 * st::webPageTitleFont->height);
}
}
if (!data->description.isEmpty()) {
_description.setText(st::webPageDescriptionFont, textClean(data->description), _webpageDescriptionOptions);
if (data->siteName == QLatin1String("Twitter")) {
_description.setText(st::webPageDescriptionFont, textClean(data->description), _twitterDescriptionOptions);
} else if (data->siteName == QLatin1String("Instagram")) {
_description.setText(st::webPageDescriptionFont, textClean(data->description), _instagramDescriptionOptions);
} else {
_description.setText(st::webPageDescriptionFont, textClean(data->description), _webpageDescriptionOptions);
}
if (_asArticle) {
_maxw = qMax(_maxw, int32(st::webPageLeft + _description.maxWidth() + st::webPagePhotoDelta + st::webPagePhotoSize));
} else {
_maxw = qMax(_maxw, int32(st::webPageLeft + _description.maxWidth() + parent->timeWidth()));
_minh += st::webPageTitleFont->height;
_minh += qMin(_description.minHeight(), 3 * st::webPageTitleFont->height);
}
}
if (!_asArticle && data->photo && (_siteNameWidth || !_title.isEmpty() || !_description.isEmpty())) {
@ -3505,33 +3550,63 @@ bool HistoryWebPage::hasPoint(int32 x, int32 y, const HistoryItem *parent, int32
return (x >= 0 && y >= 0 && x < width && y < _height);
}
TextLinkPtr HistoryWebPage::getLink(int32 x, int32 y, const HistoryItem *parent, int32 width) const {
void HistoryWebPage::getState(TextLinkPtr &lnk, bool &inText, int32 x, int32 y, const HistoryItem *parent, int32 width) const {
if (width < 0) width = w;
if (width < 1) return TextLinkPtr();
if (width < 1) return;
TextLinkPtr result = (x >= 0 && y >= 0 && x < width && y < _height) ? _openl : TextLinkPtr();
if (_photol) {
width -= st::webPageLeft;
width -= st::webPageLeft;
x -= st::webPageLeft;
if (_siteNameWidth) {
y -= st::webPageTitleFont->height;
}
if (!_title.isEmpty()) {
y -= qMin(_title.countHeight(width), st::webPageTitleFont->height * 2);
}
if (!_description.isEmpty()) {
y -= qMin(_description.countHeight(width), st::webPageDescriptionFont->height * 3);
}
if (_siteNameWidth || !_title.isEmpty() || !_description.isEmpty()) {
y -= st::webPagePhotoSkip;
}
int32 pixwidth = qMax(_pixw, int16(st::minPhotoSize)), pixheight = qMax(_pixh, int16(st::minPhotoSize));
if (x >= 0 && y >= 0 && x < pixwidth && y < pixheight) {
return _photol;
if (_asArticle) {
int32 pixwidth = st::webPagePhotoSize, pixheight = st::webPagePhotoSize;
if (x >= width - pixwidth && x < width && y >= 0 && y < pixheight) {
lnk = _openl;
return;
}
}
int32 articleLines = 5;
if (_siteNameWidth) {
y -= st::webPageTitleFont->height;
--articleLines;
}
if (!_title.isEmpty()) {
int32 availw = width;
if (_asArticle) {
availw -= st::webPagePhotoSize + st::webPagePhotoDelta;
}
int32 h = _title.countHeight(availw);
if (h > st::webPageTitleFont->height) {
articleLines -= 2;
y -= st::webPageTitleFont->height * 2;
} else {
--articleLines;
y -= h;
}
}
if (!_description.isEmpty()) {
int32 availw = width;
if (_asArticle) {
availw -= st::webPagePhotoSize + st::webPagePhotoDelta;
if (articleLines > 3) articleLines = 3;
} else if (!data->photo) {
articleLines = 3;
}
if (y >= 0 && y < st::webPageDescriptionFont->height * articleLines) {
_description.getState(lnk, inText, x, y, availw);
return;
}
y -= qMin(_description.countHeight(width), st::webPageDescriptionFont->height * articleLines);
}
if (_siteNameWidth || !_title.isEmpty() || !_description.isEmpty()) {
y -= st::webPagePhotoSkip;
}
if (!_asArticle) {
int32 pixwidth = qMax(_pixw, int16(st::minPhotoSize)), pixheight = qMax(_pixh, int16(st::minPhotoSize));
if (x >= 0 && y >= 0 && x < pixwidth && y < pixheight) {
lnk = _photol ? _photol : _openl;
return;
}
}
return result;
}
HistoryMedia *HistoryWebPage::clone() const {
@ -4150,7 +4225,7 @@ bool HistoryImageLink::hasPoint(int32 x, int32 y, const HistoryItem *parent, int
return (x >= 0 && y >= 0 && x < width && y < _height);
}
TextLinkPtr HistoryImageLink::getLink(int32 x, int32 y, const HistoryItem *parent, int32 width) const {
void HistoryImageLink::getState(TextLinkPtr &lnk, bool &inText, int32 x, int32 y, const HistoryItem *parent, int32 width) const {
if (width < 0) width = w;
int skipx = 0, skipy = 0, height = _height;
if (const HistoryReply *reply = toHistoryReply(parent)) {
@ -4162,18 +4237,20 @@ TextLinkPtr HistoryImageLink::getLink(int32 x, int32 y, const HistoryItem *paren
replyFrom = st::msgPadding.top() + st::msgNameFont->height;
skipy += replyFrom;
if (x >= st::mediaPadding.left() && y >= st::msgPadding.top() && x < width - st::mediaPadding.left() - st::mediaPadding.right() && x < st::mediaPadding.left() + parent->from()->nameText.maxWidth() && y < replyFrom) {
return parent->from()->lnk;
lnk = parent->from()->lnk;
return;
}
}
if (x >= 0 && y >= replyFrom + st::msgReplyPadding.top() && x < width && y < skipy - st::msgReplyPadding.bottom() - st::mediaPadding.top()) {
return reply->replyToLink();
lnk = reply->replyToLink();
return;
}
width -= st::mediaPadding.left() + st::mediaPadding.right();
}
if (x >= skipx && y >= skipy && x < skipx + width && y < height && data) {
return link;
lnk = link;
return;
}
return TextLinkPtr();
}
HistoryMedia *HistoryImageLink::clone() const {
@ -4366,7 +4443,11 @@ HistoryMedia *HistoryMessage::getMedia(bool inOverview) const {
}
void HistoryMessage::setMedia(const MTPmessageMedia &media) {
if (_media) return;
if (!_media && media.type() == mtpc_messageMediaEmpty) return;
if (_media) {
delete _media;
_media = 0;
}
QString t;
initMedia(media, t);
if (_media) {
@ -4578,7 +4659,7 @@ void HistoryMessage::getState(TextLinkPtr &lnk, bool &inText, int32 x, int32 y)
width = _maxw;
}
if (justMedia()) {
lnk = _media->getLink(x - left, y - st::msgMargin.top(), this);
_media->getState(lnk, inText, x - left, y - st::msgMargin.top(), this);
return;
}
QRect r(left, st::msgMargin.top(), width, _height - st::msgMargin.top() - st::msgMargin.bottom());
@ -4593,12 +4674,12 @@ void HistoryMessage::getState(TextLinkPtr &lnk, bool &inText, int32 x, int32 y)
TextLinkPtr medialnk;
if (_media) {
if (y >= trect.bottom() - _media->height() && y < trect.bottom()) {
medialnk = _media->getLink(x - trect.left(), y + _media->height() - trect.bottom(), this);
_media->getState(lnk, inText, x - trect.left(), y + _media->height() - trect.bottom(), this);
return;
}
trect.setBottom(trect.bottom() - _media->height() - st::msgPadding.bottom());
}
_text.getState(lnk, inText, x - trect.x(), y - trect.y(), trect.width());
if (!lnk && medialnk) lnk = medialnk;
}
void HistoryMessage::getSymbol(uint16 &symbol, bool &after, bool &upon, int32 x, int32 y) const {
@ -4691,7 +4772,7 @@ HistoryForwarded::HistoryForwarded(History *history, HistoryBlock *block, const
fwdNameUpdated();
}
HistoryForwarded::HistoryForwarded(History *history, HistoryBlock *block, MsgId id, HistoryMessage *msg) : HistoryMessage(history, block, id, (history->peer->input.type() != mtpc_inputPeerSelf) ? (MTPDmessage_flag_out | MTPDmessage_flag_unread) : 0, ::date(unixtime()), MTP::authedId(), msg->HistoryMessage::selectedText(FullItemSel), msg->getMedia())
HistoryForwarded::HistoryForwarded(History *history, HistoryBlock *block, MsgId id, HistoryMessage *msg) : HistoryMessage(history, block, id, (history->peer->input.type() != mtpc_inputPeerSelf) ? (MTPDmessage_flag_out | MTPDmessage_flag_unread) : 0, ::date(unixtime()), MTP::authedId(), msg->justMedia() ? QString() : msg->HistoryMessage::selectedText(FullItemSel), msg->getMedia())
, fwdDate(msg->dateForwarded())
, fwdFrom(msg->fromForwarded())
, fwdFromVersion(fwdFrom->nameVersion)
@ -5371,7 +5452,7 @@ void HistoryServiceMsg::getState(TextLinkPtr &lnk, bool &inText, int32 x, int32
return _text.getState(lnk, inText, x - trect.x(), y - trect.y(), trect.width(), Qt::AlignCenter);
}
if (_media) {
lnk = _media->getLink(x - st::msgServiceMargin.left() - (width - _media->maxWidth()) / 2, y - st::msgServiceMargin.top() - height - st::msgServiceMargin.top(), this);
_media->getState(lnk, inText, x - st::msgServiceMargin.left() - (width - _media->maxWidth()) / 2, y - st::msgServiceMargin.top() - height - st::msgServiceMargin.top(), this);
}
}

View File

@ -786,7 +786,7 @@ public:
w = qMin(width, _maxw);
return _height;
}
virtual TextLinkPtr getLink(int32 x, int32 y, const HistoryItem *parent, int32 width = -1) const = 0;
virtual void getState(TextLinkPtr &lnk, bool &inText, int32 x, int32 y, const HistoryItem *parent, int32 width = -1) const = 0;
virtual void draw(QPainter &p, const HistoryItem *parent, bool selected, int32 width = -1) const = 0;
virtual bool uploading() const {
return false;
@ -844,7 +844,7 @@ public:
const QString inDialogsText() const;
const QString inHistoryText() const;
bool hasPoint(int32 x, int32 y, const HistoryItem *parent, int32 width = -1) const;
TextLinkPtr getLink(int32 x, int32 y, const HistoryItem *parent, int32 width = -1) const;
void getState(TextLinkPtr &lnk, bool &inText, int32 x, int32 y, const HistoryItem *parent, int32 width = -1) const;
HistoryMedia *clone() const;
PhotoData *photo() const {
@ -889,7 +889,7 @@ public:
const QString inDialogsText() const;
const QString inHistoryText() const;
bool hasPoint(int32 x, int32 y, const HistoryItem *parent, int32 width = -1) const;
TextLinkPtr getLink(int32 x, int32 y, const HistoryItem *parent, int32 width = -1) const;
void getState(TextLinkPtr &lnk, bool &inText, int32 x, int32 y, const HistoryItem *parent, int32 width = -1) const;
bool uploading() const {
return (data->status == FileUploading);
}
@ -927,7 +927,7 @@ public:
const QString inDialogsText() const;
const QString inHistoryText() const;
bool hasPoint(int32 x, int32 y, const HistoryItem *parent, int32 width = -1) const;
TextLinkPtr getLink(int32 x, int32 y, const HistoryItem *parent, int32 width = -1) const;
void getState(TextLinkPtr &lnk, bool &inText, int32 x, int32 y, const HistoryItem *parent, int32 width = -1) const;
bool uploading() const {
return (data->status == FileUploading);
}
@ -964,7 +964,7 @@ public:
bool uploading() const {
return (data->status == FileUploading);
}
TextLinkPtr getLink(int32 x, int32 y, const HistoryItem *parent, int32 width = -1) const;
void getState(TextLinkPtr &lnk, bool &inText, int32 x, int32 y, const HistoryItem *parent, int32 width = -1) const;
HistoryMedia *clone() const;
DocumentData *document() {
@ -1009,7 +1009,7 @@ public:
const QString inHistoryText() const;
bool hasPoint(int32 x, int32 y, const HistoryItem *parent, int32 width = -1) const;
int32 countHeight(const HistoryItem *parent, int32 width = -1) const;
TextLinkPtr getLink(int32 x, int32 y, const HistoryItem *parent, int32 width = -1) const;
void getState(TextLinkPtr &lnk, bool &inText, int32 x, int32 y, const HistoryItem *parent, int32 width = -1) const;
HistoryMedia *clone() const;
DocumentData *document() {
@ -1044,7 +1044,7 @@ public:
const QString inDialogsText() const;
const QString inHistoryText() const;
bool hasPoint(int32 x, int32 y, const HistoryItem *parent, int32 width) const;
TextLinkPtr getLink(int32 x, int32 y, const HistoryItem *parent, int32 width) const;
void getState(TextLinkPtr &lnk, bool &inText, int32 x, int32 y, const HistoryItem *parent, int32 width) const;
HistoryMedia *clone() const;
void updateFrom(const MTPMessageMedia &media);
@ -1071,7 +1071,7 @@ public:
const QString inDialogsText() const;
const QString inHistoryText() const;
bool hasPoint(int32 x, int32 y, const HistoryItem *parent, int32 width = -1) const;
TextLinkPtr getLink(int32 x, int32 y, const HistoryItem *parent, int32 width = -1) const;
void getState(TextLinkPtr &lnk, bool &inText, int32 x, int32 y, const HistoryItem *parent, int32 width = -1) const;
HistoryMedia *clone() const;
void regItem(HistoryItem *item);
@ -1164,7 +1164,7 @@ public:
const QString inDialogsText() const;
const QString inHistoryText() const;
bool hasPoint(int32 x, int32 y, const HistoryItem *parent, int32 width = -1) const;
TextLinkPtr getLink(int32 x, int32 y, const HistoryItem *parent, int32 width = -1) const;
void getState(TextLinkPtr &lnk, bool &inText, int32 x, int32 y, const HistoryItem *parent, int32 width = -1) const;
HistoryMedia *clone() const;
private:

View File

@ -1567,6 +1567,7 @@ HistoryWidget::HistoryWidget(QWidget *parent) : QWidget(parent)
, _previewData(0)
, _previewRequest(0)
, _previewCancelled(false)
, _replyForwardPressed(false)
, _replyReturn(0)
, _lastStickersUpdate(0)
, _stickersUpdateRequest(0)
@ -2573,7 +2574,8 @@ void HistoryWidget::onSend(bool ctrlShiftEnter, MsgId replyTo) {
App::main()->readServerHistory(hist, false);
hist->loadAround(0);
App::main()->sendPreparedText(hist, text, replyTo, _previewCancelled);
WebPageId webPageId = _previewCancelled ? 0xFFFFFFFFFFFFFFFFULL : ((_previewData && _previewData->pendingTill >= 0) ? _previewData->id : 0);
App::main()->sendPreparedText(hist, text, replyTo, webPageId);
setFieldText(QString());
_saveDraftText = true;
@ -2802,6 +2804,10 @@ void HistoryWidget::leaveEvent(QEvent *e) {
}
void HistoryWidget::mouseReleaseEvent(QMouseEvent *e) {
if (_replyForwardPressed) {
_replyForwardPressed = false;
update(0, _field.y() - st::sendPadding - st::replyHeight, width(), st::replyHeight);
}
if (_attachDrag != DragStateNone || !_attachDragPhoto.isHidden() || !_attachDragDocument.isHidden()) {
_attachDrag = DragStateNone;
updateDragAreas();
@ -3510,6 +3516,10 @@ void HistoryWidget::addMessagesToBack(const QVector<MTPMessage> &messages) {
}
void HistoryWidget::mousePressEvent(QMouseEvent *e) {
_replyForwardPressed = QRect(0, _field.y() - st::replyHeight, st::replySkip, st::replyHeight).contains(e->pos());
if (_replyForwardPressed && !_replyForwardPreviewCancel.isHidden()) {
update(0, _field.y() - st::sendPadding - st::replyHeight, width(), st::replyHeight);
}
}
void HistoryWidget::keyPressEvent(QKeyEvent *e) {
@ -3664,6 +3674,7 @@ void HistoryWidget::cancelForwarding() {
}
void HistoryWidget::onReplyForwardPreviewCancel() {
_replyForwardPressed = false;
if (_previewData && _previewData->pendingTill >= 0) {
_previewCancelled = true;
previewCancel();
@ -3755,8 +3766,26 @@ void HistoryWidget::updatePreview() {
if (t <= 0) t = 1;
_previewTimer.start(t);
} else {
_previewTitle.setText(st::msgServiceNameFont, _previewData->siteName, _textNameOptions);
_previewDescription.setText(st::msgFont, _previewData->title.isEmpty() ? (_previewData->description.isEmpty() ? (_previewData->author.isEmpty() ? _previewData->url : _previewData->author) : _previewData->description) : _previewData->title, _textDlgOptions);
QString title, desc;
if (_previewData->siteName.isEmpty()) {
if (_previewData->title.isEmpty()) {
if (_previewData->description.isEmpty()) {
title = _previewData->author;
desc = _previewData->url;
} else {
title = _previewData->description;
desc = _previewData->author.isEmpty() ? _previewData->url : _previewData->author;
}
} else {
title = _previewData->title;
desc = _previewData->description.isEmpty() ? (_previewData->author.isEmpty() ? _previewData->url : _previewData->author) : _previewData->description;
}
} else {
title = _previewData->siteName;
desc = _previewData->title.isEmpty() ? (_previewData->description.isEmpty() ? (_previewData->author.isEmpty() ? _previewData->url : _previewData->author) : _previewData->description) : _previewData->title;
}
_previewTitle.setText(st::msgServiceNameFont, title, _textNameOptions);
_previewDescription.setText(st::msgFont, desc, _textDlgOptions);
}
} else if (!App::main()->hasForwardingItems() && !_replyToId) {
_replyForwardPreviewCancel.hide();
@ -3941,7 +3970,7 @@ void HistoryWidget::drawFieldBackground(QPainter &p) {
backy -= st::replyHeight;
backh += st::replyHeight;
}
bool drawPreview = (_previewData && _previewData->pendingTill >= 0);
bool drawPreview = (_previewData && _previewData->pendingTill >= 0) && !_replyForwardPressed;
p.fillRect(0, backy, width(), backh, st::taMsgField.bgColor->b);
if (_replyToId) {
int32 replyLeft = st::replySkip;

View File

@ -460,6 +460,8 @@ private:
bool _previewCancelled;
void gotPreview(QString links, const MTPMessageMedia &media, mtpRequestId req);
bool _replyForwardPressed;
HistoryItem *_replyReturn;
QList<MsgId> _replyReturns;

View File

@ -249,7 +249,7 @@ bool IntroPwdCheck::codeSubmitFail(const RPCError &error) {
}
void IntroPwdCheck::recoverStarted(const MTPauth_PasswordRecovery &result) {
_emailPattern = lng_signin_recover_hint(lt_recover_email, qs(result.c_auth_passwordRecovery().vemail_pattern));
_emailPattern = st::introFont->m.elidedText(lng_signin_recover_hint(lt_recover_email, qs(result.c_auth_passwordRecovery().vemail_pattern)), Qt::ElideRight, textRect.width());
update();
}

View File

@ -377,6 +377,9 @@ _failDifferenceTimeout(1), _lastUpdateTime(0), _cachedX(0), _cachedY(0), _backgr
connect(audioVoice(), SIGNAL(stopped(AudioData*)), this, SLOT(audioPlayProgress(AudioData*)));
}
_webPageUpdater.setSingleShot(true);
connect(&_webPageUpdater, SIGNAL(timeout()), this, SLOT(webPagesUpdate()));
connect(&_cacheBackgroundTimer, SIGNAL(timeout()), this, SLOT(onCacheBackground()));
dialogs.show();
@ -516,6 +519,25 @@ void MainWidget::finishForwarding(History *hist) {
history.peerMessagesUpdated(hist->peer->id);
}
void MainWidget::webPageUpdated(WebPageData *data) {
_webPagesUpdated.insert(data->id, true);
_webPageUpdater.start(0);
}
void MainWidget::webPagesUpdate() {
const WebPageItems &items(App::webPageItems());
for (QMap<WebPageId, bool>::const_iterator i = _webPagesUpdated.cbegin(), e = _webPagesUpdated.cend(); i != e; ++i) {
WebPageItems::const_iterator j = items.constFind(App::webPage(i.key()));
if (j != items.cend()) {
for (HistoryItemsMap::const_iterator k = j.value().cbegin(), e = j.value().cend(); k != e; ++k) {
k.key()->initDimensions();
itemResized(k.key());
}
}
}
_webPagesUpdated.clear();
}
void MainWidget::onShareContact(const PeerId &peer, UserData *contact) {
history.onShareContact(peer, contact);
}
@ -887,7 +909,7 @@ DialogsIndexed &MainWidget::contactsList() {
return dialogs.contactsList();
}
void MainWidget::sendPreparedText(History *hist, const QString &text, MsgId replyTo, bool noPreview) {
void MainWidget::sendPreparedText(History *hist, const QString &text, MsgId replyTo, WebPageId webPageId) {
saveRecentHashtags(text);
QString sendingText, leftText = text;
if (replyTo < 0) replyTo = history.replyToId();
@ -904,8 +926,14 @@ void MainWidget::sendPreparedText(History *hist, const QString &text, MsgId repl
flags |= MTPDmessage::flag_reply_to_msg_id;
sendFlags |= MTPmessages_SendMessage::flag_reply_to_msg_id;
}
if (noPreview) sendFlags |= MTPmessages_SendMessage_flag_skipWebPage;
hist->addToBack(MTP_message(MTP_int(flags), MTP_int(newId), MTP_int(MTP::authedId()), App::peerToMTP(hist->peer->id), MTPint(), MTPint(), MTP_int(replyTo), MTP_int(unixtime()), msgText, MTP_messageMediaEmpty()));
MTPMessageMedia media = MTP_messageMediaEmpty();
if (webPageId == 0xFFFFFFFFFFFFFFFFULL) {
sendFlags |= MTPmessages_SendMessage_flag_skipWebPage;
} else if (webPageId) {
WebPageData *page = App::webPage(webPageId);
media = MTP_messageMediaWebPage(MTP_webPagePending(MTP_long(page->id), MTP_int(page->pendingTill)));
}
hist->addToBack(MTP_message(MTP_int(flags), MTP_int(newId), MTP_int(MTP::authedId()), App::peerToMTP(hist->peer->id), MTPint(), MTPint(), MTP_int(replyTo), MTP_int(unixtime()), msgText, media));
hist->sendRequestId = MTP::send(MTPmessages_SendMessage(MTP_int(sendFlags), hist->peer->input, MTP_int(replyTo), msgText, MTP_long(randomId)), App::main()->rpcDone(&MainWidget::sentDataReceived, randomId), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId);
}
@ -1884,11 +1912,9 @@ void MainWidget::sentDataReceived(uint64 randomId, const MTPmessages_SentMessage
}
}
if (d.vmedia.type() != mtpc_messageMediaEmpty) {
HistoryItem *item = App::histItemById(d.vid.v);
if (item) {
item->setMedia(d.vmedia);
}
HistoryItem *item = App::histItemById(d.vid.v);
if (item) {
item->setMedia(d.vmedia);
}
} break;
@ -2773,7 +2799,7 @@ void MainWidget::handleUpdates(const MTPUpdates &updates) {
case mtpc_updateShortMessage: {
const MTPDupdateShortMessage &d(updates.c_updateShortMessage());
if (!App::userLoaded(d.vuser_id.v)) {
if (!App::userLoaded(d.vuser_id.v) || (d.has_fwd_from_id() && !App::userLoaded(d.vfwd_from_id.v))) {
return getDifference();
}
if (!updPtsUpdated(d.vpts.v, d.vpts_count.v)) {
@ -2895,15 +2921,7 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
case mtpc_updateWebPage: {
const MTPDupdateWebPage &d(update.c_updateWebPage());
WebPageData *page = App::feedWebPage(d.vwebpage);
const WebPageItems &items(App::webPageItems());
WebPageItems::const_iterator i = items.constFind(page);
if (i != items.cend()) {
for (HistoryItemsMap::const_iterator j = i.value().cbegin(), e = i.value().cend(); j != e; ++j) {
j.key()->initDimensions();
itemResized(j.key());
}
}
App::feedWebPage(d.vwebpage);
history.updatePreview();
} break;

View File

@ -283,7 +283,7 @@ public:
DialogsIndexed &contactsList();
void sendMessage(History *history, const QString &text, MsgId replyTo);
void sendPreparedText(History *hist, const QString &text, MsgId replyTo, bool noPreview = false);
void sendPreparedText(History *hist, const QString &text, MsgId replyTo, WebPageId webPageId = 0);
void saveRecentHashtags(const QString &text);
void readServerHistory(History *history, bool force = true);
@ -333,6 +333,8 @@ public:
void cancelForwarding();
void finishForwarding(History *hist); // send them
void webPageUpdated(WebPageData *page);
~MainWidget();
signals:
@ -347,6 +349,8 @@ signals:
public slots:
void webPagesUpdate();
void videoLoadProgress(mtpFileLoader *loader);
void videoLoadFailed(mtpFileLoader *loader, bool started);
void videoLoadRetry();
@ -405,6 +409,9 @@ private:
Text _toForwardFrom, _toForwardText;
int32 _toForwardNameVersion;
QMap<WebPageId, bool> _webPagesUpdated;
QTimer _webPageUpdater;
void gotDifference(const MTPupdates_Difference &diff);
bool failDifference(const RPCError &e);
void feedDifference(const MTPVector<MTPUser> &users, const MTPVector<MTPChat> &chats, const MTPVector<MTPMessage> &msgs, const MTPVector<MTPUpdate> &other);

View File

@ -825,10 +825,10 @@ void OverviewInner::onUpdateSelected() {
}
left += st::msgPhotoSkip;
}
TextLinkPtr mediaLink = media->getLink(m.x() - left, m.y() - y - st::msgMargin.top(), item, w);
if (mediaLink) {
lnk = mediaLink;
}
bool inText = false;
TextLinkPtr link;
media->getState(link, inText, m.x() - left, m.y() - y - st::msgMargin.top(), item, w);
if (link) lnk = link;
}
} else {
return;

View File

@ -11,7 +11,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>0.8.1</string>
<string>0.8.2</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleURLTypes</key>

Binary file not shown.

View File

@ -1683,7 +1683,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 0.8.1;
CURRENT_PROJECT_VERSION = 0.8.2;
DEBUG_INFORMATION_FORMAT = dwarf;
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
@ -1701,7 +1701,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
COPY_PHASE_STRIP = YES;
CURRENT_PROJECT_VERSION = 0.8.1;
CURRENT_PROJECT_VERSION = 0.8.2;
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
GCC_OPTIMIZATION_LEVEL = fast;
GCC_PREFIX_HEADER = ./SourceFiles/stdafx.h;
@ -1727,10 +1727,10 @@
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 0.8.1;
CURRENT_PROJECT_VERSION = 0.8.2;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DYLIB_COMPATIBILITY_VERSION = 0.8;
DYLIB_CURRENT_VERSION = 0.8.1;
DYLIB_CURRENT_VERSION = 0.8.2;
ENABLE_STRICT_OBJC_MSGSEND = YES;
FRAMEWORK_SEARCH_PATHS = "";
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
@ -1868,10 +1868,10 @@
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 0.8.1;
CURRENT_PROJECT_VERSION = 0.8.2;
DEBUG_INFORMATION_FORMAT = dwarf;
DYLIB_COMPATIBILITY_VERSION = 0.8;
DYLIB_CURRENT_VERSION = 0.8.1;
DYLIB_CURRENT_VERSION = 0.8.2;
ENABLE_STRICT_OBJC_MSGSEND = YES;
FRAMEWORK_SEARCH_PATHS = "";
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;

View File

@ -1,2 +1,2 @@
echo 8001 0.8.1 1
echo 8002 0.8.2 1
# AppVersion AppVersionStr DevChannel