webpage attachs redesigned

This commit is contained in:
John Preston 2015-12-19 00:36:16 +03:00
parent 840ffa6482
commit 11da39b72d
10 changed files with 452 additions and 562 deletions

View File

@ -2444,8 +2444,8 @@ namespace App {
void stopGifItems() {
if (!::gifItems.isEmpty()) {
if (HistoryItem *playing = ::gifItems.begin().value()) {
if (playing->getMedia() && playing->getMedia()->type() == MediaTypeGif) {
static_cast<HistoryGif*>(playing->getMedia())->stop(playing);
if (playing->getMedia()) {
playing->getMedia()->stopInline(playing);
}
}
}

View File

@ -482,12 +482,11 @@ public:
}
bool readNextFrame(QImage &to) {
if (_reader) _frameDelay = _reader->nextImageDelay();
if (_framesLeft < 1 && !jumpToStart()) {
return false;
}
_frameDelay = _reader->nextImageDelay();
QImage frame; // QGifHandler always reads first to internal QImage and returns it
if (!_reader->read(&frame)) {
return false;
@ -655,20 +654,17 @@ public:
}
int64 duration = av_frame_get_pkt_duration(_frame);
int64 framePts = (_frame->pkt_pts == AV_NOPTS_VALUE) ? _frame->pkt_dts : _frame->pkt_pts;
int64 frameMs = (framePts * 1000LL * _fmtContext->streams[_streamId]->time_base.num) / _fmtContext->streams[_streamId]->time_base.den;
_currentFrameDelay = _nextFrameDelay;
if (_frameMs + _currentFrameDelay < frameMs) {
_currentFrameDelay = int32(frameMs - _frameMs);
}
_frameMs = frameMs;
if (duration == AV_NOPTS_VALUE) {
int64 framePts = (_frame->pkt_pts == AV_NOPTS_VALUE) ? _frame->pkt_dts : _frame->pkt_pts;
int64 frameMs = (framePts * 1000LL * _fmtContext->streams[_streamId]->time_base.num) / _fmtContext->streams[_streamId]->time_base.den;
if (frameMs > _frameMs) {
_currentFrameDelay = int32(frameMs - _frameMs);
_frameMs = frameMs;
} else {
_currentFrameDelay = 0;
}
_nextFrameDelay = _currentFrameDelay;
_nextFrameDelay = 0;
} else {
_currentFrameDelay = _nextFrameDelay;
_nextFrameDelay = (duration * 1000LL * _fmtContext->streams[_streamId]->time_base.num) / _fmtContext->streams[_streamId]->time_base.den;
_frameMs += _nextFrameDelay;
}
av_frame_unref(_frame);

File diff suppressed because it is too large Load Diff

View File

@ -1176,6 +1176,16 @@ public:
}
virtual HistoryMedia *clone() const = 0;
virtual DocumentData *getDocument() {
return 0;
}
virtual bool playInline(HistoryItem *item) {
return false;
}
virtual void stopInline(HistoryItem *item) {
}
virtual void regItem(HistoryItem *item) {
}
@ -1204,6 +1214,9 @@ public:
}
virtual bool needsBubble(const HistoryItem *parent) const = 0;
virtual bool customInfoLayout() const = 0;
virtual QMargins bubbleMargins() const {
return QMargins();
}
virtual bool hideFromName() const {
return false;
}
@ -1225,6 +1238,7 @@ class HistoryPhoto : public HistoryMedia {
public:
HistoryPhoto(const MTPDphoto &photo, const QString &caption, HistoryItem *parent);
HistoryPhoto(PhotoData *photo);
HistoryPhoto(PeerData *chat, const MTPDphoto &photo, int32 width = 0);
void init();
@ -1459,6 +1473,9 @@ public:
bool customInfoLayout() const {
return false;
}
QMargins bubbleMargins() const {
return st::msgPadding;
}
protected:
@ -1507,7 +1524,7 @@ public:
void getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y, const HistoryItem *parent, int32 width = -1) const;
HistoryMedia *clone() const;
DocumentData *document() {
DocumentData *getDocument() {
return _data;
}
@ -1530,6 +1547,9 @@ public:
bool customInfoLayout() const {
return false;
}
QMargins bubbleMargins() const {
return withThumb() ? QMargins(st::msgFileThumbPadding.left(), st::msgFileThumbPadding.top(), st::msgFileThumbPadding.left(), st::msgFileThumbPadding.bottom()) : st::msgPadding;
}
bool hideForwardedFrom() const {
return _data->song();
}
@ -1586,9 +1606,11 @@ public:
void getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y, const HistoryItem *parent, int32 width = -1) const;
HistoryMedia *clone() const;
DocumentData *document() {
DocumentData *getDocument() {
return _data;
}
bool playInline(HistoryItem *item);
void stopInline(HistoryItem *item);
void regItem(HistoryItem *item);
void unregItem(HistoryItem *item);
@ -1613,9 +1635,6 @@ public:
return true;
}
void play(HistoryItem *parent);
void stop(HistoryItem *parent);
~HistoryGif();
protected:
@ -1760,11 +1779,15 @@ class HistoryWebPage : public HistoryMedia {
public:
HistoryWebPage(WebPageData *data);
HistoryWebPage(const HistoryWebPage &other);
void initDimensions(const HistoryItem *parent);
void linkOver(HistoryItem *parent, const TextLinkPtr &lnk);
void linkOut(HistoryItem *parent, const TextLinkPtr &lnk);
void draw(Painter &p, const HistoryItem *parent, const QRect &r, bool selected, uint64 ms) const;
bool isDisplayed() const {
return !data->pendingTill;
return !_data->pendingTill;
}
int32 resize(int32 width, const HistoryItem *parent);
HistoryMediaType type() const {
@ -1776,21 +1799,32 @@ public:
void getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y, const HistoryItem *parent, int32 width = -1) const;
HistoryMedia *clone() const;
DocumentData *getDocument() {
return _attach ? _attach->getDocument() : 0;
}
bool playInline(HistoryItem *item) {
return _attach ? _attach->playInline(item) : false;
}
void stopInline(HistoryItem *item) {
if (_attach) _attach->stopInline(item);
}
void regItem(HistoryItem *item);
void unregItem(HistoryItem *item);
bool hasReplyPreview() const {
return (data->photo && !data->photo->thumb->isNull()) || (data->doc && !data->doc->thumb->isNull());
return (_data->photo && !_data->photo->thumb->isNull()) || (_data->doc && !_data->doc->thumb->isNull());
}
ImagePtr replyPreview();
virtual bool animating() const {
if (_asArticle || !data->photo || data->photo->full->loaded()) return false;
return data->photo->full->loading();
return _attach ? _attach->animating() : false;
}
WebPageData *webpage() {
return data;
return _data;
}
bool needsBubble(const HistoryItem *parent) const {
@ -1801,17 +1835,18 @@ public:
}
private:
WebPageData *data;
TextLinkPtr _openl, _attachl;
WebPageData *_data;
TextLinkPtr _openl;
HistoryMedia *_attach;
bool _asArticle;
int32 _titleLines, _descriptionLines;
Text _title, _description;
int32 _siteNameWidth;
QString _duration, _docName, _docSize;
int32 _durationWidth, _docNameWidth, _docThumbWidth;
mutable QString _docDownloadTextCache;
mutable int32 _docDownloadDone;
QString _duration;
int32 _durationWidth;
int16 _pixw, _pixh;
};

View File

@ -5363,14 +5363,7 @@ void HistoryWidget::onDocumentUploaded(const FullMsgId &newId, const MTPInputFil
if (!MTP::authedId()) return;
HistoryMessage *item = dynamic_cast<HistoryMessage*>(App::histItemById(newId));
if (item) {
DocumentData *document = 0;
if (HistoryDocument *media = dynamic_cast<HistoryDocument*>(item->getMedia())) {
document = media->document();
} else if (HistoryGif *media = dynamic_cast<HistoryGif*>(item->getMedia())) {
document = media->document();
} else if (HistorySticker *media = dynamic_cast<HistorySticker*>(item->getMedia())) {
document = media->document();
}
DocumentData *document = item->getMedia() ? item->getMedia()->getDocument() : 0;
if (document) {
uint64 randomId = MTP::nonce<uint64>();
App::historyRegRandom(randomId, newId);
@ -5394,14 +5387,7 @@ void HistoryWidget::onThumbDocumentUploaded(const FullMsgId &newId, const MTPInp
if (!MTP::authedId()) return;
HistoryMessage *item = dynamic_cast<HistoryMessage*>(App::histItemById(newId));
if (item) {
DocumentData *document = 0;
if (HistoryDocument *media = dynamic_cast<HistoryDocument*>(item->getMedia())) {
document = media->document();
} else if (HistoryGif *media = dynamic_cast<HistoryGif*>(item->getMedia())) {
document = media->document();
} else if (HistorySticker *media = dynamic_cast<HistorySticker*>(item->getMedia())) {
document = media->document();
}
DocumentData *document = item->getMedia() ? item->getMedia()->getDocument() : 0;
if (document) {
uint64 randomId = MTP::nonce<uint64>();
App::historyRegRandom(randomId, newId);
@ -5463,17 +5449,7 @@ void HistoryWidget::onDocumentProgress(const FullMsgId &newId) {
if (!MTP::authedId()) return;
if (HistoryItem *item = App::histItemById(newId)) {
HistoryMedia *media = item->getMedia();
DocumentData *doc = 0;
if (media) {
HistoryMediaType type = media->type();
if (type == MediaTypeDocument) {
doc = static_cast<HistoryDocument*>(item->getMedia())->document();
} else if (type == MediaTypeGif) {
doc = static_cast<HistoryGif*>(item->getMedia())->document();
} else if (type == MediaTypeSticker) {
doc = static_cast<HistorySticker*>(item->getMedia())->document();
}
}
DocumentData *doc = media ? media->getDocument() : 0;
if (!item->fromChannel()) {
updateSendAction(item->history(), SendActionUploadFile, doc ? doc->uploadOffset : 0);
}

View File

@ -1883,9 +1883,7 @@ void MainWidget::documentLoadProgress(mtpFileLoader *loader) {
} else if (document->openOnSave > 0 && document->size < MediaViewImageSizeLimit) {
const FileLocation &location(document->location(true));
if (location.accessEnable()) {
if (item && item->getMedia() && item->getMedia()->type() == MediaTypeGif) {
static_cast<HistoryGif*>(item->getMedia())->play(item);
} else {
if (!item || !item->getMedia() || !item->getMedia()->playInline(item)) {
QImageReader reader(location.name());
if (reader.canRead() && item) {
App::wnd()->showDocument(document, item);

View File

@ -346,7 +346,7 @@ void MediaView::updateControls() {
_dateText = lng_mediaview_date_time(lt_date, d.date().toString(qsl("dd.MM.yy")), lt_time, d.time().toString(cTimeFormat()));
}
if (_from) {
_fromName.setText(st::mvFont, (_from->migrateTo() ? _from->migrateTo() : _from)->name);
_fromName.setText(st::mvFont, (_from->migrateTo() ? _from->migrateTo() : _from)->name, _textNameOptions);
_nameNav = myrtlrect(st::mvTextLeft, height() - st::mvTextTop, qMin(_fromName.maxWidth(), width() / 3), st::mvFont->height);
_dateNav = myrtlrect(st::mvTextLeft + _nameNav.width() + st::mvTextSkip, height() - st::mvTextTop, st::mvFont->width(_dateText), st::mvFont->height);
} else {
@ -1513,8 +1513,8 @@ void MediaView::moveToNext(int32 delta) {
if (item->getMedia()) {
switch (item->getMedia()->type()) {
case MediaTypePhoto: displayPhoto(static_cast<HistoryPhoto*>(item->getMedia())->photo(), item); preloadData(delta); break;
case MediaTypeDocument: displayDocument(static_cast<HistoryDocument*>(item->getMedia())->document(), item); preloadData(delta); break;
case MediaTypeGif: displayDocument(static_cast<HistoryGif*>(item->getMedia())->document(), item); preloadData(delta); break;
case MediaTypeDocument: displayDocument(static_cast<HistoryDocument*>(item->getMedia())->getDocument(), item); preloadData(delta); break;
case MediaTypeGif: displayDocument(static_cast<HistoryGif*>(item->getMedia())->getDocument(), item); preloadData(delta); break;
case MediaTypeSticker: displayDocument(static_cast<HistorySticker*>(item->getMedia())->document(), item); preloadData(delta); break;
}
} else {
@ -1561,8 +1561,8 @@ void MediaView::preloadData(int32 delta) {
if (HistoryMedia *media = item->getMedia()) {
switch (media->type()) {
case MediaTypePhoto: static_cast<HistoryPhoto*>(media)->photo()->full->load(); break;
case MediaTypeDocument: static_cast<HistoryDocument*>(media)->document()->thumb->load(); break;
case MediaTypeGif: static_cast<HistoryGif*>(media)->document()->thumb->load(); break;
case MediaTypeDocument: static_cast<HistoryDocument*>(media)->getDocument()->thumb->load(); break;
case MediaTypeGif: static_cast<HistoryGif*>(media)->getDocument()->thumb->load(); break;
case MediaTypeSticker: static_cast<HistorySticker*>(media)->document()->sticker()->img->load(); break;
}
}
@ -1585,8 +1585,8 @@ void MediaView::preloadData(int32 delta) {
if (HistoryMedia *media = item->getMedia()) {
switch (media->type()) {
case MediaTypePhoto: static_cast<HistoryPhoto*>(media)->photo()->forget(); break;
case MediaTypeDocument: static_cast<HistoryDocument*>(media)->document()->forget(); break;
case MediaTypeGif: static_cast<HistoryGif*>(media)->document()->forget(); break;
case MediaTypeDocument: static_cast<HistoryDocument*>(media)->getDocument()->forget(); break;
case MediaTypeGif: static_cast<HistoryGif*>(media)->getDocument()->forget(); break;
case MediaTypeSticker: static_cast<HistorySticker*>(media)->document()->forget(); break;
}
}

View File

@ -323,11 +323,12 @@ void PlayerWidget::preloadNext() {
}
if (next) {
if (HistoryDocument *document = static_cast<HistoryDocument*>(next->getMedia())) {
if (document->document()->location(true).isEmpty() && document->document()->data.isEmpty()) {
if (!document->document()->loader) {
DocumentOpenLink::doOpen(document->document());
document->document()->openOnSave = 0;
document->document()->openOnSaveMsgId = FullMsgId();
DocumentData *d = document->getDocument();
if (d->location(true).isEmpty() && d->data.isEmpty()) {
if (!d->loader) {
DocumentOpenLink::doOpen(d);
d->openOnSave = 0;
d->openOnSaveMsgId = FullMsgId();
}
}
}
@ -337,7 +338,7 @@ void PlayerWidget::preloadNext() {
void PlayerWidget::startPlay(const FullMsgId &msgId) {
if (HistoryItem *item = App::histItemById(msgId)) {
if (HistoryDocument *doc = static_cast<HistoryDocument*>(item->getMedia())) {
audioPlayer()->play(SongMsgId(doc->document(), item->fullId()));
audioPlayer()->play(SongMsgId(doc->getDocument(), item->fullId()));
updateState();
}
}

View File

@ -886,9 +886,7 @@ void DocumentOpenLink::doOpen(DocumentData *data) {
if (App::main()) App::main()->documentPlayProgress(song);
}
} else if (data->size < MediaViewImageSizeLimit && location.accessEnable()) {
if (App::hoveredLinkItem() && App::hoveredLinkItem()->getMedia() && App::hoveredLinkItem()->getMedia()->type() == MediaTypeGif) {
static_cast<HistoryGif*>(App::hoveredLinkItem()->getMedia())->play(App::hoveredLinkItem());
} else {
if (!App::hoveredLinkItem() || !App::hoveredLinkItem()->getMedia() || !App::hoveredLinkItem()->getMedia()->playInline(App::hoveredLinkItem())) {
QImageReader reader(location.name());
if (reader.canRead() && (App::hoveredLinkItem() || App::contextItem())) {
App::wnd()->showDocument(data, App::hoveredLinkItem() ? App::hoveredLinkItem() : App::contextItem());

View File

@ -1145,6 +1145,9 @@ struct DocumentData {
SongData *song() {
return (type == SongDocument) ? static_cast<SongData*>(_additional) : 0;
}
bool isAnimation() {
return (type == AnimatedDocument) || !mime.compare(qstr("image/gif"), Qt::CaseInsensitive);
}
bool isImage() const {
return _isImage;
}