Apply web page media updates.

This commit is contained in:
John Preston 2017-12-31 12:39:21 +03:00
parent 9551cfaf9b
commit 6796ac688a
7 changed files with 261 additions and 68 deletions

View File

@ -1290,7 +1290,23 @@ namespace {
}
WebPageData *feedWebPage(const MTPDwebPagePending &webpage, WebPageData *convert) {
return App::webPageSet(webpage.vid.v, convert, QString(), QString(), QString(), QString(), QString(), TextWithEntities(), nullptr, nullptr, 0, QString(), webpage.vdate.v);
constexpr auto kDefaultPendingTimeout = 60;
return App::webPageSet(
webpage.vid.v,
convert,
QString(),
QString(),
QString(),
QString(),
QString(),
TextWithEntities(),
nullptr,
nullptr,
0,
QString(),
webpage.vdate.v
? webpage.vdate.v
: (unixtime() + kDefaultPendingTimeout));
}
WebPageData *feedWebPage(const MTPWebPage &webpage) {
@ -1603,9 +1619,9 @@ namespace {
const TextWithEntities &description,
PhotoData *photo,
DocumentData *document,
int32 duration,
int duration,
const QString &author,
int32 pendingTill) {
int pendingTill) {
if (convert) {
if (convert->id != webPage) {
const auto i = webPagesData.find(convert->id);
@ -1614,23 +1630,18 @@ namespace {
}
convert->id = webPage;
}
if ((convert->url.isEmpty() && !url.isEmpty()) || (convert->pendingTill && convert->pendingTill != pendingTill && pendingTill >= -1)) {
convert->type = toWebPageType(type);
convert->url = TextUtilities::Clean(url);
convert->displayUrl = TextUtilities::Clean(displayUrl);
convert->siteName = TextUtilities::Clean(siteName);
convert->title = TextUtilities::SingleLine(title);
convert->description = description;
convert->photo = photo;
convert->document = document;
convert->duration = duration;
convert->author = TextUtilities::Clean(author);
if (convert->pendingTill > 0 && pendingTill <= 0) {
Auth().api().clearWebPageRequest(convert);
}
convert->pendingTill = pendingTill;
if (App::main()) App::main()->webPageUpdated(convert);
}
convert->applyChanges(
type,
url,
displayUrl,
siteName,
title,
description,
photo,
document,
duration,
author,
pendingTill);
}
const auto i = webPagesData.constFind(webPage);
WebPageData *result;
@ -1638,7 +1649,19 @@ namespace {
if (convert) {
result = convert;
} else {
result = new WebPageData(webPage, toWebPageType(type), url, displayUrl, siteName, title, description, document, photo, duration, author, (pendingTill >= -1) ? pendingTill : -1);
result = new WebPageData(
webPage,
toWebPageType(type),
url,
displayUrl,
siteName,
title,
description,
document,
photo,
duration,
author,
(pendingTill >= -1) ? pendingTill : -1);
if (pendingTill > 0) {
Auth().api().requestWebPageDelayed(result);
}
@ -1647,23 +1670,18 @@ namespace {
} else {
result = i.value();
if (result != convert) {
if ((result->url.isEmpty() && !url.isEmpty()) || (result->pendingTill && result->pendingTill != pendingTill && pendingTill >= -1)) {
result->type = toWebPageType(type);
result->url = TextUtilities::Clean(url);
result->displayUrl = TextUtilities::Clean(displayUrl);
result->siteName = TextUtilities::Clean(siteName);
result->title = TextUtilities::SingleLine(title);
result->description = description;
result->photo = photo;
result->document = document;
result->duration = duration;
result->author = TextUtilities::Clean(author);
if (result->pendingTill > 0 && pendingTill <= 0) {
Auth().api().clearWebPageRequest(result);
}
result->pendingTill = pendingTill;
if (App::main()) App::main()->webPageUpdated(result);
}
result->applyChanges(
type,
url,
displayUrl,
siteName,
title,
description,
photo,
document,
duration,
author,
pendingTill);
}
}
return result;

View File

@ -133,13 +133,52 @@ namespace App {
PeerData *peerByName(const QString &username);
QString peerName(const PeerData *peer, bool forDialogs = false);
PhotoData *photo(const PhotoId &photo);
PhotoData *photoSet(const PhotoId &photo, PhotoData *convert, const uint64 &access, int32 date, const ImagePtr &thumb, const ImagePtr &medium, const ImagePtr &full);
PhotoData *photoSet(
const PhotoId &photo,
PhotoData *convert,
const uint64 &access,
int32 date,
const ImagePtr &thumb,
const ImagePtr &medium,
const ImagePtr &full);
DocumentData *document(const DocumentId &document);
DocumentData *documentSet(const DocumentId &document, DocumentData *convert, const uint64 &access, int32 version, int32 date, const QVector<MTPDocumentAttribute> &attributes, const QString &mime, const ImagePtr &thumb, int32 dc, int32 size, const StorageImageLocation &thumbLocation);
DocumentData *documentSet(
const DocumentId &document,
DocumentData *convert,
const uint64 &access,
int32 version,
int32 date,
const QVector<MTPDocumentAttribute> &attributes,
const QString &mime,
const ImagePtr &thumb,
int32 dc,
int32 size,
const StorageImageLocation &thumbLocation);
WebPageData *webPage(const WebPageId &webPage);
WebPageData *webPageSet(const WebPageId &webPage, WebPageData *convert, const QString &type, const QString &url, const QString &displayUrl, const QString &siteName, const QString &title, const TextWithEntities &description, PhotoData *photo, DocumentData *doc, int32 duration, const QString &author, int32 pendingTill);
WebPageData *webPageSet(
const WebPageId &webPage,
WebPageData *convert,
const QString &type,
const QString &url,
const QString &displayUrl,
const QString &siteName,
const QString &title,
const TextWithEntities &description,
PhotoData *photo,
DocumentData *document,
int duration,
const QString &author,
int pendingTill);
GameData *game(const GameId &game);
GameData *gameSet(const GameId &game, GameData *convert, const uint64 &accessHash, const QString &shortName, const QString &title, const QString &description, PhotoData *photo, DocumentData *doc);
GameData *gameSet(
const GameId &game,
GameData *convert,
const uint64 &accessHash,
const QString &shortName,
const QString &title,
const QString &description,
PhotoData *photo,
DocumentData *document);
LocationData *location(const LocationCoords &coords);
void forgetMedia();

View File

@ -0,0 +1,122 @@
/*
This file is part of Telegram Desktop,
the official desktop version of Telegram messaging app, see https://telegram.org
Telegram Desktop is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
It is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
In addition, as a special exception, the copyright holders give permission
to link the code of portions of this program with the OpenSSL library.
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
*/
#include "data/data_web_page.h"
#include "auth_session.h"
#include "apiwrap.h"
#include "mainwidget.h"
#include "ui/text/text_entity.h"
namespace {
QString SiteNameFromUrl(const QString &url) {
QUrl u(url);
QString pretty = u.isValid() ? u.toDisplayString() : url;
QRegularExpressionMatch m = QRegularExpression(qsl("^[a-zA-Z0-9]+://")).match(pretty);
if (m.hasMatch()) pretty = pretty.mid(m.capturedLength());
int32 slash = pretty.indexOf('/');
if (slash > 0) pretty = pretty.mid(0, slash);
QStringList components = pretty.split('.', QString::SkipEmptyParts);
if (components.size() >= 2) {
components = components.mid(components.size() - 2);
return components.at(0).at(0).toUpper() + components.at(0).mid(1) + '.' + components.at(1);
}
return QString();
}
} // namespace
bool WebPageData::applyChanges(
const QString &newType,
const QString &newUrl,
const QString &newDisplayUrl,
const QString &newSiteName,
const QString &newTitle,
const TextWithEntities &newDescription,
PhotoData *newPhoto,
DocumentData *newDocument,
int newDuration,
const QString &newAuthor,
int newPendingTill) {
if (newPendingTill != 0
&& (!url.isEmpty() || newUrl.isEmpty())
&& (!pendingTill
|| pendingTill == newPendingTill
|| newPendingTill < -1)) {
return false;
}
const auto resultType = toWebPageType(newType);
const auto resultUrl = TextUtilities::Clean(newUrl);
const auto resultDisplayUrl = TextUtilities::Clean(
newDisplayUrl);
const auto possibleSiteName = TextUtilities::Clean(
newSiteName);
const auto resultTitle = TextUtilities::SingleLine(
newTitle);
const auto resultAuthor = TextUtilities::Clean(newAuthor);
const auto viewTitleText = resultTitle.isEmpty()
? TextUtilities::SingleLine(resultAuthor)
: resultTitle;
const auto resultSiteName = [&] {
if (!possibleSiteName.isEmpty()) {
return possibleSiteName;
} else if (!newDescription.text.isEmpty()
&& viewTitleText.isEmpty()
&& !resultUrl.isEmpty()) {
return SiteNameFromUrl(resultUrl);
}
return QString();
}();
if (type == resultType
&& url == resultUrl
&& displayUrl == resultDisplayUrl
&& siteName == resultSiteName
&& title == resultTitle
&& description.text == newDescription.text
&& photo == newPhoto
&& document == newDocument
&& duration == newDuration
&& author == resultAuthor
&& pendingTill == newPendingTill) {
return false;
}
if (pendingTill > 0 && newPendingTill <= 0) {
Auth().api().clearWebPageRequest(this);
}
type = resultType;
url = resultUrl;
displayUrl = resultDisplayUrl;
siteName = resultSiteName;
title = resultTitle;
description = newDescription;
photo = newPhoto;
document = newDocument;
duration = newDuration;
author = resultAuthor;
pendingTill = newPendingTill;
++version;
if (App::main()) App::main()->webPageUpdated(this);
return true;
}

View File

@ -50,9 +50,9 @@ struct WebPageData {
const TextWithEntities &description,
DocumentData *document,
PhotoData *photo,
int32 duration,
int duration,
const QString &author,
int32 pendingTill)
int pendingTill)
: id(id)
, type(type)
, url(url)
@ -72,6 +72,19 @@ struct WebPageData {
if (photo) photo->forget();
}
bool applyChanges(
const QString &newType,
const QString &newUrl,
const QString &newDisplayUrl,
const QString &newSiteName,
const QString &newTitle,
const TextWithEntities &newDescription,
PhotoData *newPhoto,
DocumentData *newDocument,
int newDuration,
const QString &newAuthor,
int newPendingTill);
WebPageId id = 0;
WebPageType type = WebPageArticle;
QString url;
@ -79,10 +92,11 @@ struct WebPageData {
QString siteName;
QString title;
TextWithEntities description;
int32 duration = 0;
int duration = 0;
QString author;
PhotoData *photo = nullptr;
DocumentData *document = nullptr;
int32 pendingTill = 0;
int pendingTill = 0;
int version = 0;
};

View File

@ -3567,21 +3567,6 @@ TextWithEntities HistoryCall::selectedText(TextSelection selection) const {
namespace {
QString siteNameFromUrl(const QString &url) {
QUrl u(url);
QString pretty = u.isValid() ? u.toDisplayString() : url;
QRegularExpressionMatch m = QRegularExpression(qsl("^[a-zA-Z0-9]+://")).match(pretty);
if (m.hasMatch()) pretty = pretty.mid(m.capturedLength());
int32 slash = pretty.indexOf('/');
if (slash > 0) pretty = pretty.mid(0, slash);
QStringList components = pretty.split('.', QString::SkipEmptyParts);
if (components.size() >= 2) {
components = components.mid(components.size() - 2);
return components.at(0).at(0).toUpper() + components.at(0).mid(1) + '.' + components.at(1);
}
return QString();
}
int32 articleThumbWidth(PhotoData *thumb, int32 height) {
int32 w = thumb->medium->width(), h = thumb->medium->height();
return qMax(qMin(height * w / h, height), 1);
@ -3623,6 +3608,18 @@ void HistoryWebPage::initDimensions() {
_maxw = _minh = _height = 0;
return;
}
const auto versionChanged = (_dataVersion != _data->version);
if (versionChanged) {
_dataVersion = _data->version;
_openl = nullptr;
if (_attach) {
_attach->detachFromParent();
_attach = nullptr;
}
_title = Text(st::msgMinWidth - st::webPageLeft);
_description = Text(st::msgMinWidth - st::webPageLeft);
_siteNameWidth = 0;
}
auto lineHeight = unitedLineHeight();
if (!_openl && !_data->url.isEmpty()) {
@ -3631,9 +3628,6 @@ void HistoryWebPage::initDimensions() {
// init layout
auto title = TextUtilities::SingleLine(_data->title.isEmpty() ? _data->author : _data->title);
if (!_data->description.text.isEmpty() && title.isEmpty() && _data->siteName.isEmpty() && !_data->url.isEmpty()) {
_data->siteName = siteNameFromUrl(_data->url);
}
if (!_data->document && _data->photo && _data->type != WebPagePhoto && _data->type != WebPageVideo) {
if (_data->type == WebPageProfile) {
_asArticle = true;
@ -3650,7 +3644,7 @@ void HistoryWebPage::initDimensions() {
}
// init attach
if (!_asArticle && !_attach) {
if (!_attach && !_asArticle) {
if (_data->document) {
if (_data->document->sticker()) {
_attach = std::make_unique<HistorySticker>(_parent, _data->document);
@ -3664,6 +3658,9 @@ void HistoryWebPage::initDimensions() {
} else if (_data->photo) {
_attach = std::make_unique<HistoryPhoto>(_parent, _data->photo, QString());
}
if (_attach) {
_attach->attachToParent();
}
}
auto textFloatsAroundInfo = !_asArticle && !_attach && isBubbleBottom();

View File

@ -942,13 +942,15 @@ private:
std::unique_ptr<HistoryMedia> _attach;
bool _asArticle = false;
int32 _titleLines, _descriptionLines;
int _dataVersion = -1;
int _titleLines = 0;
int _descriptionLines = 0;
Text _title, _description;
int32 _siteNameWidth = 0;
int _siteNameWidth = 0;
QString _duration;
int32 _durationWidth = 0;
int _durationWidth = 0;
int16 _pixw = 0;
int16 _pixh = 0;

View File

@ -187,6 +187,7 @@
<(src_loc)/data/data_types.h
<(src_loc)/data/data_user_photos.cpp
<(src_loc)/data/data_user_photos.h
<(src_loc)/data/data_web_page.cpp
<(src_loc)/data/data_web_page.h
<(src_loc)/dialogs/dialogs_common.h
<(src_loc)/dialogs/dialogs_indexed_list.cpp