gif autoplay improved

This commit is contained in:
John Preston 2015-12-23 22:23:14 +03:00
parent 6170144fe9
commit b94533fcb2
18 changed files with 401 additions and 226 deletions

View File

@ -149,6 +149,7 @@ void StickerSetInner::paintEvent(QPaintEvent *e) {
} else { } else {
bool already = !doc->already().isEmpty(), hasdata = !doc->data.isEmpty(); bool already = !doc->already().isEmpty(), hasdata = !doc->data.isEmpty();
if (!already && !hasdata && !doc->loader && doc->status == FileReady) { if (!already && !hasdata && !doc->loader && doc->status == FileReady) {
doc->openOnSave = 0;
doc->save(QString()); doc->save(QString());
} }
if (doc->sticker()->img->isNull() && (already || hasdata)) { if (doc->sticker()->img->isNull() && (already || hasdata)) {

View File

@ -1333,6 +1333,7 @@ void StickerPanInner::paintEvent(QPaintEvent *e) {
} else { } else {
bool already = !sticker->already().isEmpty(), hasdata = !sticker->data.isEmpty(); bool already = !sticker->already().isEmpty(), hasdata = !sticker->data.isEmpty();
if (!already && !hasdata && !sticker->loader && sticker->status == FileReady) { if (!already && !hasdata && !sticker->loader && sticker->status == FileReady) {
sticker->openOnSave = 0;
sticker->save(QString()); sticker->save(QString());
} }
if (sticker->sticker()->img->isNull() && (already || hasdata)) { if (sticker->sticker()->img->isNull() && (already || hasdata)) {
@ -1522,6 +1523,7 @@ void StickerPanInner::preloadImages() {
} else { } else {
bool already = !sticker->already().isEmpty(), hasdata = !sticker->data.isEmpty(); bool already = !sticker->already().isEmpty(), hasdata = !sticker->data.isEmpty();
if (!already && !hasdata && !sticker->loader && sticker->status == FileReady) { if (!already && !hasdata && !sticker->loader && sticker->status == FileReady) {
sticker->openOnSave = 0;
sticker->save(QString()); sticker->save(QString());
} }
//if (sticker->sticker->img->isNull() && (already || hasdata)) { //if (sticker->sticker->img->isNull() && (already || hasdata)) {

View File

@ -3773,11 +3773,12 @@ void HistoryAudio::draw(Painter &p, const HistoryItem *parent, const QRect &r, b
bool out = parent->out(), fromChannel = parent->fromChannel(), outbg = out && !fromChannel; bool out = parent->out(), fromChannel = parent->fromChannel(), outbg = out && !fromChannel;
bool loaded = _data->loaded(); bool loaded = _data->loaded();
if (!loaded && _data->status == FileReady && _data->loader && !_data->loader->loading() && !_data->loader->paused()) { if (!loaded && _data->status == FileReady && _data->loader && !_data->loadingStarted()) {
_data->openOnSave = 0;
_data->save(QString()); _data->save(QString());
} }
if (_data->loader && (_data->loader->loading() || _data->loader->paused())) { if (_data->loadingStarted() && !_data->loader->loadingLocal()) {
ensureAnimation(parent); ensureAnimation(parent);
if (!_animation->radial.animating()) { if (!_animation->radial.animating()) {
_animation->radial.start(_data->progress()); _animation->radial.start(_data->progress());
@ -3802,7 +3803,7 @@ void HistoryAudio::draw(Painter &p, const HistoryItem *parent, const QRect &r, b
float64 over = _animation->a_thumbOver.current(); float64 over = _animation->a_thumbOver.current();
p.setBrush(style::interpolate(outbg ? st::msgFileOutBg : st::msgFileInBg, outbg ? st::msgFileOutBgOver : st::msgFileInBgOver, over)); p.setBrush(style::interpolate(outbg ? st::msgFileOutBg : st::msgFileInBg, outbg ? st::msgFileOutBgOver : st::msgFileInBgOver, over));
} else { } else {
bool over = textlnkDrawOver(_data->loader ? _cancell : _savel); bool over = textlnkDrawOver(_data->loadingStarted() ? _cancell : _savel);
p.setBrush(outbg ? (over ? st::msgFileOutBgOver : st::msgFileOutBg) : (over ? st::msgFileInBgOver : st::msgFileInBg)); p.setBrush(outbg ? (over ? st::msgFileOutBgOver : st::msgFileOutBg) : (over ? st::msgFileInBgOver : st::msgFileInBg));
} }
@ -3821,7 +3822,7 @@ void HistoryAudio::draw(Painter &p, const HistoryItem *parent, const QRect &r, b
icon = outbg ? (selected ? st::msgFileOutPauseSelected : st::msgFileOutPause) : (selected ? st::msgFileInPauseSelected : st::msgFileInPause); icon = outbg ? (selected ? st::msgFileOutPauseSelected : st::msgFileOutPause) : (selected ? st::msgFileInPauseSelected : st::msgFileInPause);
} else if (_statusSize < 0 || _statusSize == FileStatusSizeLoaded) { } else if (_statusSize < 0 || _statusSize == FileStatusSizeLoaded) {
icon = outbg ? (selected ? st::msgFileOutPlaySelected : st::msgFileOutPlay) : (selected ? st::msgFileInPlaySelected : st::msgFileInPlay); icon = outbg ? (selected ? st::msgFileOutPlaySelected : st::msgFileOutPlay) : (selected ? st::msgFileInPlaySelected : st::msgFileInPlay);
} else if (_data->loader) { } else if (_data->loadingStarted()) {
icon = outbg ? (selected ? st::msgFileOutCancelSelected : st::msgFileOutCancel) : (selected ? st::msgFileInCancelSelected : st::msgFileInCancel); icon = outbg ? (selected ? st::msgFileOutCancelSelected : st::msgFileOutCancel) : (selected ? st::msgFileInCancelSelected : st::msgFileInCancel);
} else { } else {
icon = outbg ? (selected ? st::msgFileOutDownloadSelected : st::msgFileOutDownload) : (selected ? st::msgFileInDownloadSelected : st::msgFileInDownload); icon = outbg ? (selected ? st::msgFileOutDownloadSelected : st::msgFileOutDownload) : (selected ? st::msgFileInDownloadSelected : st::msgFileInDownload);
@ -3856,19 +3857,19 @@ void HistoryAudio::getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x
if (_width < st::msgPadding.left() + st::msgPadding.right() + 1) return; if (_width < st::msgPadding.left() + st::msgPadding.right() + 1) return;
bool out = parent->out(), fromChannel = parent->fromChannel(), outbg = out && !fromChannel; bool out = parent->out(), fromChannel = parent->fromChannel(), outbg = out && !fromChannel;
bool already = !_data->already().isEmpty(), hasdata = !_data->data.isEmpty(); bool loaded = _data->loaded();
bool showPause = updateStatusText(parent); bool showPause = updateStatusText(parent);
int32 nameleft = 0, nametop = 0, nameright = 0, statustop = 0, linktop = 0; int32 nameleft = 0, nametop = 0, nameright = 0, statustop = 0, linktop = 0;
QRect inner(rtlrect(st::msgFilePadding.left(), st::msgFilePadding.top(), st::msgFileSize, st::msgFileSize, _width)); QRect inner(rtlrect(st::msgFilePadding.left(), st::msgFilePadding.top(), st::msgFileSize, st::msgFileSize, _width));
if ((_data->loader || _data->status == FileUploading || (!already && !hasdata)) && inner.contains(x, y)) { if ((_data->loadingStarted() || _data->status == FileUploading || !loaded) && inner.contains(x, y)) {
lnk = (_data->loader || _data->status == FileUploading) ? _cancell : _savel; lnk = (_data->loadingStarted() || _data->status == FileUploading) ? _cancell : _savel;
return; return;
} }
if (x >= 0 && y >= 0 && x < _width && y < _height && !_data->loader && _data->access) { if (x >= 0 && y >= 0 && x < _width && y < _height && !_data->loadingStarted() && _data->access) {
lnk = _openl; lnk = _openl;
return; return;
} }
@ -3910,9 +3911,9 @@ bool HistoryAudio::updateStatusText(const HistoryItem *parent) const {
statusSize = FileStatusSizeFailed; statusSize = FileStatusSizeFailed;
} else if (_data->status == FileUploading) { } else if (_data->status == FileUploading) {
statusSize = _data->uploadOffset; statusSize = _data->uploadOffset;
} else if (_data->loader) { } else if (_data->loadingStarted()) {
statusSize = _data->loader->currentOffset(); statusSize = _data->loader->currentOffset();
} else if (!_data->already().isEmpty() || !_data->data.isEmpty()) { } else if (_data->loaded()) {
AudioMsgId playing; AudioMsgId playing;
AudioPlayerState playingState = AudioPlayerStopped; AudioPlayerState playingState = AudioPlayerStopped;
int64 playingPosition = 0, playingDuration = 0; int64 playingPosition = 0, playingDuration = 0;
@ -4002,9 +4003,9 @@ void HistoryDocument::draw(Painter &p, const HistoryItem *parent, const QRect &r
if (_width < st::msgPadding.left() + st::msgPadding.right() + 1) return; if (_width < st::msgPadding.left() + st::msgPadding.right() + 1) return;
bool out = parent->out(), fromChannel = parent->fromChannel(), outbg = out && !fromChannel; bool out = parent->out(), fromChannel = parent->fromChannel(), outbg = out && !fromChannel;
bool already = !_data->already().isEmpty(), hasdata = !_data->data.isEmpty(); bool loaded = _data->loaded();
if (_data->loader) { if (_data->loadingStarted()) {
ensureAnimation(parent); ensureAnimation(parent);
if (!_animation->radial.animating()) { if (!_animation->radial.animating()) {
_animation->radial.start(_data->progress()); _animation->radial.start(_data->progress());
@ -4024,7 +4025,7 @@ void HistoryDocument::draw(Painter &p, const HistoryItem *parent, const QRect &r
QRect rthumb(rtlrect(st::msgFileThumbPadding.left(), st::msgFileThumbPadding.top(), st::msgFileThumbSize, st::msgFileThumbSize, _width)); QRect rthumb(rtlrect(st::msgFileThumbPadding.left(), st::msgFileThumbPadding.top(), st::msgFileThumbSize, st::msgFileThumbSize, _width));
if (_data->thumb->loaded()) { if (_data->thumb->loaded()) {
QPixmap thumb = (already || hasdata) ? _data->thumb->pixSingle(_thumbw, 0, st::msgFileThumbSize, st::msgFileThumbSize) : _data->thumb->pixBlurredSingle(_thumbw, 0, st::msgFileThumbSize, st::msgFileThumbSize); QPixmap thumb = loaded ? _data->thumb->pixSingle(_thumbw, 0, st::msgFileThumbSize, st::msgFileThumbSize) : _data->thumb->pixBlurredSingle(_thumbw, 0, st::msgFileThumbSize, st::msgFileThumbSize);
p.drawPixmap(rthumb.topLeft(), thumb); p.drawPixmap(rthumb.topLeft(), thumb);
} else { } else {
App::roundRect(p, rthumb, st::black, BlackCorners); App::roundRect(p, rthumb, st::black, BlackCorners);
@ -4033,13 +4034,12 @@ void HistoryDocument::draw(Painter &p, const HistoryItem *parent, const QRect &r
App::roundRect(p, rthumb, textstyleCurrent()->selectOverlay, SelectedOverlayCorners); App::roundRect(p, rthumb, textstyleCurrent()->selectOverlay, SelectedOverlayCorners);
} }
if (!radial && (already || hasdata)) { if (radial || !loaded) {
} else {
QRect inner(rthumb.x() + (rthumb.width() - st::msgFileSize) / 2, rthumb.y() + (rthumb.height() - st::msgFileSize) / 2, st::msgFileSize, st::msgFileSize); QRect inner(rthumb.x() + (rthumb.width() - st::msgFileSize) / 2, rthumb.y() + (rthumb.height() - st::msgFileSize) / 2, st::msgFileSize, st::msgFileSize);
p.setPen(Qt::NoPen); p.setPen(Qt::NoPen);
if (selected) { if (selected) {
p.setBrush(st::msgDateImgBgSelected); p.setBrush(st::msgDateImgBgSelected);
} else if (radial && (already || hasdata)) { } else if (radial && loaded) {
p.setOpacity(st::msgDateImgBg->c.alphaF() * _animation->radial.opacity()); p.setOpacity(st::msgDateImgBg->c.alphaF() * _animation->radial.opacity());
p.setBrush(st::black); p.setBrush(st::black);
} else if (_animation && _animation->_a_thumbOver.animating()) { } else if (_animation && _animation->_a_thumbOver.animating()) {
@ -4048,7 +4048,7 @@ void HistoryDocument::draw(Painter &p, const HistoryItem *parent, const QRect &r
p.setOpacity((st::msgDateImgBg->c.alphaF() * (1 - over)) + (st::msgDateImgBgOver->c.alphaF() * over)); p.setOpacity((st::msgDateImgBg->c.alphaF() * (1 - over)) + (st::msgDateImgBgOver->c.alphaF() * over));
p.setBrush(st::black); p.setBrush(st::black);
} else { } else {
bool over = textlnkDrawOver(_data->loader ? _cancell : _savel); bool over = textlnkDrawOver(_data->loadingStarted() ? _cancell : _savel);
p.setBrush(over ? st::msgDateImgBgOver : st::msgDateImgBg); p.setBrush(over ? st::msgDateImgBgOver : st::msgDateImgBg);
} }
@ -4057,7 +4057,7 @@ void HistoryDocument::draw(Painter &p, const HistoryItem *parent, const QRect &r
p.setRenderHint(QPainter::HighQualityAntialiasing, false); p.setRenderHint(QPainter::HighQualityAntialiasing, false);
style::sprite icon; style::sprite icon;
if (already || hasdata || _data->loader) { if (loaded || _data->loadingStarted()) {
icon = (selected ? st::msgFileInCancelSelected : st::msgFileInCancel); icon = (selected ? st::msgFileInCancelSelected : st::msgFileInCancel);
} else { } else {
icon = (selected ? st::msgFileInDownloadSelected : st::msgFileInDownload); icon = (selected ? st::msgFileInDownloadSelected : st::msgFileInDownload);
@ -4073,7 +4073,7 @@ void HistoryDocument::draw(Painter &p, const HistoryItem *parent, const QRect &r
} }
if (_data->status != FileUploadFailed) { if (_data->status != FileUploadFailed) {
const TextLinkPtr &lnk((_data->loader || _data->status == FileUploading) ? _linkcancell : _linksavel); const TextLinkPtr &lnk((_data->loadingStarted() || _data->status == FileUploading) ? _linkcancell : _linksavel);
bool over = textlnkDrawOver(lnk); bool over = textlnkDrawOver(lnk);
p.setFont(over ? st::semiboldFont->underline() : st::semiboldFont); p.setFont(over ? st::semiboldFont->underline() : st::semiboldFont);
p.setPen(outbg ? (selected ? st::msgFileThumbLinkOutFgSelected : st::msgFileThumbLinkOutFg) : (selected ? st::msgFileThumbLinkInFgSelected : st::msgFileThumbLinkInFg)); p.setPen(outbg ? (selected ? st::msgFileThumbLinkOutFgSelected : st::msgFileThumbLinkOutFg) : (selected ? st::msgFileThumbLinkInFgSelected : st::msgFileThumbLinkInFg));
@ -4093,7 +4093,7 @@ void HistoryDocument::draw(Painter &p, const HistoryItem *parent, const QRect &r
float64 over = _animation->a_thumbOver.current(); float64 over = _animation->a_thumbOver.current();
p.setBrush(style::interpolate(outbg ? st::msgFileOutBg : st::msgFileInBg, outbg ? st::msgFileOutBgOver : st::msgFileInBgOver, over)); p.setBrush(style::interpolate(outbg ? st::msgFileOutBg : st::msgFileInBg, outbg ? st::msgFileOutBgOver : st::msgFileInBgOver, over));
} else { } else {
bool over = textlnkDrawOver(_data->loader ? _cancell : _savel); bool over = textlnkDrawOver(_data->loadingStarted() ? _cancell : _savel);
p.setBrush(outbg ? (over ? st::msgFileOutBgOver : st::msgFileOutBg) : (over ? st::msgFileInBgOver : st::msgFileInBg)); p.setBrush(outbg ? (over ? st::msgFileOutBgOver : st::msgFileOutBg) : (over ? st::msgFileInBgOver : st::msgFileInBg));
} }
@ -4118,7 +4118,7 @@ void HistoryDocument::draw(Painter &p, const HistoryItem *parent, const QRect &r
} else { } else {
icon = outbg ? (selected ? st::msgFileOutFileSelected : st::msgFileOutFile) : (selected ? st::msgFileInFileSelected : st::msgFileInFile); icon = outbg ? (selected ? st::msgFileOutFileSelected : st::msgFileOutFile) : (selected ? st::msgFileInFileSelected : st::msgFileInFile);
} }
} else if (_data->loader) { } else if (_data->loadingStarted()) {
icon = outbg ? (selected ? st::msgFileOutCancelSelected : st::msgFileOutCancel) : (selected ? st::msgFileInCancelSelected : st::msgFileInCancel); icon = outbg ? (selected ? st::msgFileOutCancelSelected : st::msgFileOutCancel) : (selected ? st::msgFileInCancelSelected : st::msgFileInCancel);
} else { } else {
icon = outbg ? (selected ? st::msgFileOutDownloadSelected : st::msgFileOutDownload) : (selected ? st::msgFileInDownloadSelected : st::msgFileInDownload); icon = outbg ? (selected ? st::msgFileOutDownloadSelected : st::msgFileOutDownload) : (selected ? st::msgFileInDownloadSelected : st::msgFileInDownload);
@ -4145,7 +4145,7 @@ void HistoryDocument::getState(TextLinkPtr &lnk, HistoryCursorState &state, int3
if (_width < st::msgPadding.left() + st::msgPadding.right() + 1) return; if (_width < st::msgPadding.left() + st::msgPadding.right() + 1) return;
bool out = parent->out(), fromChannel = parent->fromChannel(), outbg = out && !fromChannel; bool out = parent->out(), fromChannel = parent->fromChannel(), outbg = out && !fromChannel;
bool already = !_data->already().isEmpty(), hasdata = !_data->data.isEmpty(); bool loaded = _data->loaded();
bool showPause = updateStatusText(parent); bool showPause = updateStatusText(parent);
@ -4157,28 +4157,28 @@ void HistoryDocument::getState(TextLinkPtr &lnk, HistoryCursorState &state, int3
QRect rthumb(rtlrect(st::msgFileThumbPadding.left(), st::msgFileThumbPadding.top(), st::msgFileThumbSize, st::msgFileThumbSize, _width)); QRect rthumb(rtlrect(st::msgFileThumbPadding.left(), st::msgFileThumbPadding.top(), st::msgFileThumbSize, st::msgFileThumbSize, _width));
if (already || hasdata) { if (loaded) {
} else { } else {
if (rthumb.contains(x, y)) { if (rthumb.contains(x, y)) {
lnk = (_data->loader || _data->status == FileUploading) ? _cancell : _savel; lnk = (_data->loadingStarted() || _data->status == FileUploading) ? _cancell : _savel;
return; return;
} }
} }
if (_data->status != FileUploadFailed) { if (_data->status != FileUploadFailed) {
if (rtlrect(nameleft, linktop, _linkw, st::semiboldFont->height, _width).contains(x, y)) { if (rtlrect(nameleft, linktop, _linkw, st::semiboldFont->height, _width).contains(x, y)) {
lnk = (_data->loader || _data->status == FileUploading) ? _linkcancell : _linksavel; lnk = (_data->loadingStarted() || _data->status == FileUploading) ? _linkcancell : _linksavel;
return; return;
} }
} }
} else { } else {
QRect inner(rtlrect(st::msgFilePadding.left(), st::msgFilePadding.top(), st::msgFileSize, st::msgFileSize, _width)); QRect inner(rtlrect(st::msgFilePadding.left(), st::msgFilePadding.top(), st::msgFileSize, st::msgFileSize, _width));
if ((_data->loader || _data->status == FileUploading || (!already && !hasdata)) && inner.contains(x, y)) { if ((_data->loadingStarted() || _data->status == FileUploading || !loaded) && inner.contains(x, y)) {
lnk = (_data->loader || _data->status == FileUploading) ? _cancell : _savel; lnk = (_data->loadingStarted() || _data->status == FileUploading) ? _cancell : _savel;
return; return;
} }
} }
if (x >= 0 && y >= 0 && x < _width && y < _height && !_data->loader && _data->access) { if (x >= 0 && y >= 0 && x < _width && y < _height && !_data->loadingStarted() && _data->access) {
lnk = _openl; lnk = _openl;
return; return;
} }
@ -4216,29 +4216,31 @@ bool HistoryDocument::updateStatusText(const HistoryItem *parent) const {
statusSize = FileStatusSizeFailed; statusSize = FileStatusSizeFailed;
} else if (_data->status == FileUploading) { } else if (_data->status == FileUploading) {
statusSize = _data->uploadOffset; statusSize = _data->uploadOffset;
} else if (_data->loader) { } else if (_data->loadingStarted()) {
statusSize = _data->loader->currentOffset(); statusSize = _data->loader->currentOffset();
} else if (_data->song() && (!_data->already().isEmpty() || !_data->data.isEmpty())) { } else if (_data->loaded()) {
SongMsgId playing; if (_data->song()) {
AudioPlayerState playingState = AudioPlayerStopped; SongMsgId playing;
int64 playingPosition = 0, playingDuration = 0; AudioPlayerState playingState = AudioPlayerStopped;
int32 playingFrequency = 0; int64 playingPosition = 0, playingDuration = 0;
if (audioPlayer()) { int32 playingFrequency = 0;
audioPlayer()->currentState(&playing, &playingState, &playingPosition, &playingDuration, &playingFrequency); if (audioPlayer()) {
} audioPlayer()->currentState(&playing, &playingState, &playingPosition, &playingDuration, &playingFrequency);
}
if (playing.msgId == parent->fullId() && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) { if (playing.msgId == parent->fullId() && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) {
statusSize = -1 - (playingPosition / (playingFrequency ? playingFrequency : AudioVoiceMsgFrequency)); statusSize = -1 - (playingPosition / (playingFrequency ? playingFrequency : AudioVoiceMsgFrequency));
realDuration = playingDuration / (playingFrequency ? playingFrequency : AudioVoiceMsgFrequency); realDuration = playingDuration / (playingFrequency ? playingFrequency : AudioVoiceMsgFrequency);
showPause = (playingState == AudioPlayerPlaying || playingState == AudioPlayerResuming || playingState == AudioPlayerStarting); showPause = (playingState == AudioPlayerPlaying || playingState == AudioPlayerResuming || playingState == AudioPlayerStarting);
} else {
statusSize = FileStatusSizeLoaded;
}
if (!showPause && playing.msgId == parent->fullId() && App::main() && App::main()->player()->seekingSong(playing)) {
showPause = true;
}
} else { } else {
statusSize = FileStatusSizeLoaded; statusSize = FileStatusSizeLoaded;
} }
if (!showPause && playing.msgId == parent->fullId() && App::main() && App::main()->player()->seekingSong(playing)) {
showPause = true;
}
} else if (!_data->already().isEmpty() || !_data->data.isEmpty()) {
statusSize = FileStatusSizeLoaded;
} else { } else {
statusSize = FileStatusSizeReady; statusSize = FileStatusSizeReady;
} }
@ -4394,7 +4396,8 @@ void HistoryGif::draw(Painter &p, const HistoryItem *parent, const QRect &r, boo
bool out = parent->out(), fromChannel = parent->fromChannel(), outbg = out && !fromChannel; bool out = parent->out(), fromChannel = parent->fromChannel(), outbg = out && !fromChannel;
bool loaded = _data->loaded(_gif ? false : true); bool loaded = _data->loaded(_gif ? false : true);
if (!loaded && _data->status == FileReady && _data->loader && !_data->loader->loading() && !_data->loader->paused()) { if (!loaded && _data->status == FileReady && _data->loader && !_data->loadingStarted()) {
_data->openOnSave = 0;
_data->save(QString()); _data->save(QString());
} }
if (loaded && !_gif) { if (loaded && !_gif) {
@ -4404,7 +4407,7 @@ void HistoryGif::draw(Painter &p, const HistoryItem *parent, const QRect &r, boo
bool animating = (_gif && _gif->started()); bool animating = (_gif && _gif->started());
if (!animating) { if (!animating) {
if (_data->loader && !_data->loader->tryingLocal()) { if (_data->loadingStarted() && !_data->loader->loadingLocal()) {
ensureAnimation(parent); ensureAnimation(parent);
if (!_animation->radial.animating()) { if (!_animation->radial.animating()) {
_animation->radial.start(_data->progress()); _animation->radial.start(_data->progress());
@ -4436,7 +4439,7 @@ void HistoryGif::draw(Painter &p, const HistoryItem *parent, const QRect &r, boo
App::roundRect(p, rthumb, textstyleCurrent()->selectOverlay, SelectedOverlayCorners); App::roundRect(p, rthumb, textstyleCurrent()->selectOverlay, SelectedOverlayCorners);
} }
if (radial || (!animating && !_gif && (!_data->loader || !_data->loader->tryingLocal() || _data->size > AnimationInMemory))) { if (radial || (!animating && !_gif && (!_data->loader || !_data->loader->loadingLocal() || _data->size > AnimationInMemory))) {
QRect inner(rthumb.x() + (rthumb.width() - st::msgFileSize) / 2, rthumb.y() + (rthumb.height() - st::msgFileSize) / 2, st::msgFileSize, st::msgFileSize); QRect inner(rthumb.x() + (rthumb.width() - st::msgFileSize) / 2, rthumb.y() + (rthumb.height() - st::msgFileSize) / 2, st::msgFileSize, st::msgFileSize);
p.setPen(Qt::NoPen); p.setPen(Qt::NoPen);
if (selected) { if (selected) {
@ -4447,7 +4450,7 @@ void HistoryGif::draw(Painter &p, const HistoryItem *parent, const QRect &r, boo
p.setOpacity((st::msgDateImgBg->c.alphaF() * (1 - over)) + (st::msgDateImgBgOver->c.alphaF() * over)); p.setOpacity((st::msgDateImgBg->c.alphaF() * (1 - over)) + (st::msgDateImgBgOver->c.alphaF() * over));
p.setBrush(st::black); p.setBrush(st::black);
} else { } else {
bool over = textlnkDrawOver(_data->loader ? _cancell : _savel); bool over = textlnkDrawOver(_data->loadingStarted() ? _cancell : _savel);
p.setBrush(over ? st::msgDateImgBgOver : st::msgDateImgBg); p.setBrush(over ? st::msgDateImgBgOver : st::msgDateImgBg);
} }
@ -4462,7 +4465,7 @@ void HistoryGif::draw(Painter &p, const HistoryItem *parent, const QRect &r, boo
style::sprite icon; style::sprite icon;
if (_data->loaded() && !radial) { if (_data->loaded() && !radial) {
icon = (selected ? st::msgFileInPlaySelected : st::msgFileInPlay); icon = (selected ? st::msgFileInPlaySelected : st::msgFileInPlay);
} else if (_data->loader || radial) { } else if (_data->loadingStarted() || radial) {
icon = (selected ? st::msgFileInCancelSelected : st::msgFileInCancel); icon = (selected ? st::msgFileInCancelSelected : st::msgFileInCancel);
} else { } else {
icon = (selected ? st::msgFileInDownloadSelected : st::msgFileInDownload); icon = (selected ? st::msgFileInDownloadSelected : st::msgFileInDownload);
@ -4505,7 +4508,7 @@ void HistoryGif::getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x,
if (x >= skipx && y >= skipy && x < skipx + width && y < skipy + height) { if (x >= skipx && y >= skipy && x < skipx + width && y < skipy + height) {
if (_gif && _gif->started()) { if (_gif && _gif->started()) {
} else { } else {
lnk = _data->loaded() ? _savel : (_data->loader ? _cancell : _savel); lnk = _data->loaded() ? _savel : (_data->loadingStarted() ? _cancell : _savel);
} }
if (parent->getMedia() == this) { if (parent->getMedia() == this) {
@ -4538,7 +4541,7 @@ void HistoryGif::updateStatusText(const HistoryItem *parent) const {
statusSize = FileStatusSizeFailed; statusSize = FileStatusSizeFailed;
} else if (_data->status == FileUploading) { } else if (_data->status == FileUploading) {
statusSize = _data->uploadOffset; statusSize = _data->uploadOffset;
} else if (_data->loader) { } else if (_data->loadingStarted()) {
statusSize = _data->loader->currentOffset(); statusSize = _data->loader->currentOffset();
} else if (_data->loaded()) { } else if (_data->loaded()) {
statusSize = FileStatusSizeLoaded; statusSize = FileStatusSizeLoaded;
@ -4636,7 +4639,8 @@ void HistorySticker::draw(Painter &p, const HistoryItem *parent, const QRect &r,
bool out = parent->out(), fromChannel = parent->fromChannel(), outbg = out && !fromChannel, hovered, pressed; bool out = parent->out(), fromChannel = parent->fromChannel(), outbg = out && !fromChannel, hovered, pressed;
bool loaded = _data->loaded(); bool loaded = _data->loaded();
if (!loaded && _data->status == FileReady && _data->loader && !_data->loader->loading() && !_data->loader->paused()) { if (!loaded && _data->status == FileReady && _data->loader && !_data->loader->started()) {
_data->openOnSave = 0;
_data->save(QString()); _data->save(QString());
} }

View File

@ -880,7 +880,7 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
_menu->addAction(lang(lng_context_save_image), this, SLOT(saveContextImage()))->setEnabled(true); _menu->addAction(lang(lng_context_save_image), this, SLOT(saveContextImage()))->setEnabled(true);
_menu->addAction(lang(lng_context_copy_image), this, SLOT(copyContextImage()))->setEnabled(true); _menu->addAction(lang(lng_context_copy_image), this, SLOT(copyContextImage()))->setEnabled(true);
} else { } else {
if ((lnkVideo && lnkVideo->video()->loader) || (lnkAudio && lnkAudio->audio()->loader) || (lnkDocument && lnkDocument->document()->loader)) { if ((lnkVideo && lnkVideo->video()->loader) || (lnkAudio && lnkAudio->audio()->loadingStarted()) || (lnkDocument && lnkDocument->document()->loadingStarted())) {
_menu->addAction(lang(lng_context_cancel_download), this, SLOT(cancelContextDownload()))->setEnabled(true); _menu->addAction(lang(lng_context_cancel_download), this, SLOT(cancelContextDownload()))->setEnabled(true);
} else { } else {
if ((lnkVideo && !lnkVideo->video()->already(true).isEmpty()) || (lnkAudio && !lnkAudio->audio()->already(true).isEmpty()) || (lnkDocument && !lnkDocument->document()->already(true).isEmpty())) { if ((lnkVideo && !lnkVideo->video()->already(true).isEmpty()) || (lnkAudio && !lnkAudio->audio()->already(true).isEmpty()) || (lnkDocument && !lnkDocument->document()->already(true).isEmpty())) {
@ -1063,12 +1063,15 @@ void HistoryInner::showContextInFolder() {
} }
void HistoryInner::openContextFile() { void HistoryInner::openContextFile() {
VideoLink *lnkVideo = dynamic_cast<VideoLink*>(_contextMenuLnk.data()); HistoryItem *was = App::hoveredLinkItem();
App::hoveredLinkItem(App::contextItem());
VideoLink *lnkVideo = dynamic_cast<VideoLink*>(_contextMenuLnk.data());
AudioLink *lnkAudio = dynamic_cast<AudioLink*>(_contextMenuLnk.data()); AudioLink *lnkAudio = dynamic_cast<AudioLink*>(_contextMenuLnk.data());
DocumentLink *lnkDocument = dynamic_cast<DocumentLink*>(_contextMenuLnk.data()); DocumentLink *lnkDocument = dynamic_cast<DocumentLink*>(_contextMenuLnk.data());
if (lnkVideo) VideoOpenLink(lnkVideo->video()).onClick(Qt::LeftButton); if (lnkVideo) VideoOpenLink(lnkVideo->video()).onClick(Qt::LeftButton);
if (lnkAudio) AudioOpenLink(lnkAudio->audio()).onClick(Qt::LeftButton); if (lnkAudio) AudioOpenLink(lnkAudio->audio()).onClick(Qt::LeftButton);
if (lnkDocument) DocumentOpenLink(lnkDocument->document()).onClick(Qt::LeftButton); if (lnkDocument) DocumentOpenLink(lnkDocument->document()).onClick(Qt::LeftButton);
App::hoveredLinkItem(was);
} }
void HistoryInner::saveContextFile() { void HistoryInner::saveContextFile() {

View File

@ -275,6 +275,7 @@ QPixmap StickerPreviewWidget::currentImage() const {
if (_doc && _cacheStatus != CacheLoaded) { if (_doc && _cacheStatus != CacheLoaded) {
bool already = !_doc->already().isEmpty(), hasdata = !_doc->data.isEmpty(); bool already = !_doc->already().isEmpty(), hasdata = !_doc->data.isEmpty();
if (!already && !hasdata && !_doc->loader && _doc->status == FileReady) { if (!already && !hasdata && !_doc->loader && _doc->status == FileReady) {
_doc->openOnSave = 0;
_doc->save(QString()); _doc->save(QString());
} }
if (_doc->sticker()->img->isNull() && (already || hasdata)) { if (_doc->sticker()->img->isNull() && (already || hasdata)) {

View File

@ -551,13 +551,13 @@ void LayoutOverviewAudio::initDimensions() {
void LayoutOverviewAudio::paint(Painter &p, const QRect &clip, uint32 selection, const PaintContext *context) const { void LayoutOverviewAudio::paint(Painter &p, const QRect &clip, uint32 selection, const PaintContext *context) const {
bool selected = (selection == FullSelection); bool selected = (selection == FullSelection);
bool already = !_data->already().isEmpty(), hasdata = !_data->data.isEmpty(); bool loaded = _data->loaded();
if (!loaded && _data->status == FileReady && _data->loader && !_data->loadingStarted()) {
if (!_data->loader && _data->status == FileReady && !already && !hasdata && _data->size < AudioVoiceMsgInMemory) { _data->openOnSave = 0;
_data->save(QString()); _data->save(QString());
} }
if (_data->loader) { if (_data->loadingStarted() && !_data->loader->loadingLocal()) {
ensureRadial(); ensureRadial();
if (!_radial->animating()) { if (!_radial->animating()) {
_radial->start(_data->progress()); _radial->start(_data->progress());
@ -591,7 +591,7 @@ void LayoutOverviewAudio::paint(Painter &p, const QRect &clip, uint32 selection,
float64 over = a_iconOver.current(); float64 over = a_iconOver.current();
p.setBrush(style::interpolate(st::msgFileInBg, st::msgFileInBgOver, over)); p.setBrush(style::interpolate(st::msgFileInBg, st::msgFileInBgOver, over));
} else { } else {
bool over = textlnkDrawOver((already || hasdata) ? _openl : (_data->loader ? _cancell : _savel)); bool over = textlnkDrawOver(loaded ? _openl : (_data->loadingStarted() ? _cancell : _savel));
p.setBrush(over ? st::msgFileInBgOver : st::msgFileInBg); p.setBrush(over ? st::msgFileInBgOver : st::msgFileInBg);
} }
@ -610,7 +610,7 @@ void LayoutOverviewAudio::paint(Painter &p, const QRect &clip, uint32 selection,
icon = selected ? st::msgFileInPauseSelected : st::msgFileInPause; icon = selected ? st::msgFileInPauseSelected : st::msgFileInPause;
} else if (_statusSize < 0 || _statusSize == FileStatusSizeLoaded) { } else if (_statusSize < 0 || _statusSize == FileStatusSizeLoaded) {
icon = selected ? st::msgFileInPlaySelected : st::msgFileInPlay; icon = selected ? st::msgFileInPlaySelected : st::msgFileInPlay;
} else if (_data->loader) { } else if (_data->loadingStarted()) {
icon = selected ? st::msgFileInCancelSelected : st::msgFileInCancel; icon = selected ? st::msgFileInCancelSelected : st::msgFileInCancel;
} else { } else {
icon = selected ? st::msgFileInDownloadSelected : st::msgFileInDownload; icon = selected ? st::msgFileInDownloadSelected : st::msgFileInDownload;
@ -639,7 +639,7 @@ void LayoutOverviewAudio::paint(Painter &p, const QRect &clip, uint32 selection,
} }
void LayoutOverviewAudio::getState(TextLinkPtr &link, HistoryCursorState &cursor, int32 x, int32 y) const { void LayoutOverviewAudio::getState(TextLinkPtr &link, HistoryCursorState &cursor, int32 x, int32 y) const {
bool already = !_data->already().isEmpty(), hasdata = !_data->data.isEmpty(); bool loaded = _data->loaded();
bool showPause = updateStatusText(); bool showPause = updateStatusText();
@ -652,7 +652,7 @@ void LayoutOverviewAudio::getState(TextLinkPtr &link, HistoryCursorState &cursor
QRect inner(rtlrect(st::msgFilePadding.left(), st::msgFilePadding.top(), st::msgFileSize, st::msgFileSize, _width)); QRect inner(rtlrect(st::msgFilePadding.left(), st::msgFilePadding.top(), st::msgFileSize, st::msgFileSize, _width));
if (inner.contains(x, y)) { if (inner.contains(x, y)) {
link = (already || hasdata) ? _openl : ((_data->loader || _data->status == FileUploading) ? _cancell : _savel); link = loaded ? _openl : ((_data->loadingStarted() || _data->status == FileUploading) ? _cancell : _savel);
return; return;
} }
if (rtlrect(nameleft, statustop, _width - nameleft - nameright, st::normalFont->height, _width).contains(x, y)) { if (rtlrect(nameleft, statustop, _width - nameleft - nameright, st::normalFont->height, _width).contains(x, y)) {
@ -709,6 +709,7 @@ bool LayoutOverviewAudio::updateStatusText() const {
LayoutOverviewDocument::LayoutOverviewDocument(DocumentData *document, HistoryItem *parent) : LayoutAbstractFileItem(parent) LayoutOverviewDocument::LayoutOverviewDocument(DocumentData *document, HistoryItem *parent) : LayoutAbstractFileItem(parent)
, _data(document) , _data(document)
, _msgl(new MessageLink(parent)) , _msgl(new MessageLink(parent))
, _namel(new DocumentOpenLink(_data))
, _name(documentName(_data)) , _name(documentName(_data))
, _date(langDateTime(date(_data->date))) , _date(langDateTime(date(_data->date)))
, _namew(st::semiboldFont->width(_name)) , _namew(st::semiboldFont->width(_name))
@ -748,8 +749,8 @@ void LayoutOverviewDocument::initDimensions() {
void LayoutOverviewDocument::paint(Painter &p, const QRect &clip, uint32 selection, const PaintContext *context) const { void LayoutOverviewDocument::paint(Painter &p, const QRect &clip, uint32 selection, const PaintContext *context) const {
bool selected = (selection == FullSelection); bool selected = (selection == FullSelection);
bool already = !_data->already().isEmpty(), hasdata = !_data->data.isEmpty(); bool loaded = _data->loaded() || (_data->loader && _data->loader->localAvailable());
if (_data->loader) { if (_data->loadingStarted() && !_data->loader->loadingLocal()) {
ensureRadial(); ensureRadial();
if (!_radial->animating()) { if (!_radial->animating()) {
_radial->start(_data->progress()); _radial->start(_data->progress());
@ -780,7 +781,7 @@ void LayoutOverviewDocument::paint(Painter &p, const QRect &clip, uint32 selecti
float64 over = a_iconOver.current(); float64 over = a_iconOver.current();
p.setBrush(style::interpolate(st::msgFileInBg, st::msgFileInBgOver, over)); p.setBrush(style::interpolate(st::msgFileInBg, st::msgFileInBgOver, over));
} else { } else {
bool over = textlnkDrawOver(already ? _openl : (_data->loader ? _cancell : _savel)); bool over = textlnkDrawOver(loaded ? _openl : (_data->loadingStarted() ? _cancell : _savel));
p.setBrush(over ? st::msgFileInBgOver : st::msgFileInBg); p.setBrush(over ? st::msgFileInBgOver : st::msgFileInBg);
} }
@ -799,7 +800,7 @@ void LayoutOverviewDocument::paint(Painter &p, const QRect &clip, uint32 selecti
icon = selected ? st::msgFileInPauseSelected : st::msgFileInPause; icon = selected ? st::msgFileInPauseSelected : st::msgFileInPause;
} else if (_statusSize < 0 || _statusSize == FileStatusSizeLoaded) { } else if (_statusSize < 0 || _statusSize == FileStatusSizeLoaded) {
icon = selected ? st::msgFileInPlaySelected : st::msgFileInPlay; icon = selected ? st::msgFileInPlaySelected : st::msgFileInPlay;
} else if (_data->loader) { } else if (_data->loadingStarted() && !_data->loader->loadingLocal()) {
icon = selected ? st::msgFileInCancelSelected : st::msgFileInCancel; icon = selected ? st::msgFileInCancelSelected : st::msgFileInCancel;
} else { } else {
icon = selected ? st::msgFileInDownloadSelected : st::msgFileInDownload; icon = selected ? st::msgFileInDownloadSelected : st::msgFileInDownload;
@ -821,14 +822,14 @@ void LayoutOverviewDocument::paint(Painter &p, const QRect &clip, uint32 selecti
if (clip.intersects(rthumb)) { if (clip.intersects(rthumb)) {
if (wthumb) { if (wthumb) {
if (_data->thumb->loaded()) { if (_data->thumb->loaded()) {
QPixmap thumb = (already || hasdata) ? _data->thumb->pixSingle(_thumbw, 0, st::msgFileThumbSize, st::msgFileThumbSize) : _data->thumb->pixBlurredSingle(_thumbw, 0, st::msgFileThumbSize, st::msgFileThumbSize); QPixmap thumb = loaded ? _data->thumb->pixSingle(_thumbw, 0, st::msgFileThumbSize, st::msgFileThumbSize) : _data->thumb->pixBlurredSingle(_thumbw, 0, st::msgFileThumbSize, st::msgFileThumbSize);
p.drawPixmap(rthumb.topLeft(), thumb); p.drawPixmap(rthumb.topLeft(), thumb);
} else { } else {
App::roundRect(p, rthumb, st::black, BlackCorners); App::roundRect(p, rthumb, st::black, BlackCorners);
} }
} else { } else {
App::roundRect(p, rthumb, documentColor(_colorIndex), documentCorners(_colorIndex)); App::roundRect(p, rthumb, documentColor(_colorIndex), documentCorners(_colorIndex));
if (!radial && (already || hasdata)) { if (!radial && loaded) {
style::sprite icon = documentCorner(_colorIndex); style::sprite icon = documentCorner(_colorIndex);
p.drawSprite(rthumb.topLeft() + QPoint(rtl() ? 0 : (rthumb.width() - icon.pxWidth()), 0), icon); p.drawSprite(rthumb.topLeft() + QPoint(rtl() ? 0 : (rthumb.width() - icon.pxWidth()), 0), icon);
if (!_ext.isEmpty()) { if (!_ext.isEmpty()) {
@ -842,14 +843,13 @@ void LayoutOverviewDocument::paint(Painter &p, const QRect &clip, uint32 selecti
App::roundRect(p, rthumb, textstyleCurrent()->selectOverlay, SelectedOverlayCorners); App::roundRect(p, rthumb, textstyleCurrent()->selectOverlay, SelectedOverlayCorners);
} }
if (!radial && (already || hasdata)) { if (radial || (!loaded && !_data->loadingStarted())) {
} else {
QRect inner(rthumb.x() + (rthumb.width() - st::msgFileSize) / 2, rthumb.y() + (rthumb.height() - st::msgFileSize) / 2, st::msgFileSize, st::msgFileSize); QRect inner(rthumb.x() + (rthumb.width() - st::msgFileSize) / 2, rthumb.y() + (rthumb.height() - st::msgFileSize) / 2, st::msgFileSize, st::msgFileSize);
if (clip.intersects(inner)) { if (clip.intersects(inner)) {
p.setPen(Qt::NoPen); p.setPen(Qt::NoPen);
if (selected) { if (selected) {
p.setBrush(st::msgDateImgBgSelected); p.setBrush(st::msgDateImgBgSelected);
} else if (radial && (already || hasdata)) { } else if (radial && loaded) {
p.setOpacity(st::msgDateImgBg->c.alphaF() * _radial->opacity()); p.setOpacity(st::msgDateImgBg->c.alphaF() * _radial->opacity());
p.setBrush(st::black); p.setBrush(st::black);
} else if (_a_iconOver.animating()) { } else if (_a_iconOver.animating()) {
@ -858,7 +858,7 @@ void LayoutOverviewDocument::paint(Painter &p, const QRect &clip, uint32 selecti
p.setOpacity((st::msgDateImgBg->c.alphaF() * (1 - over)) + (st::msgDateImgBgOver->c.alphaF() * over)); p.setOpacity((st::msgDateImgBg->c.alphaF() * (1 - over)) + (st::msgDateImgBgOver->c.alphaF() * over));
p.setBrush(st::black); p.setBrush(st::black);
} else { } else {
bool over = textlnkDrawOver(_data->loader ? _cancell : _savel); bool over = textlnkDrawOver(_data->loadingStarted() ? _cancell : _savel);
p.setBrush(over ? st::msgDateImgBgOver : st::msgDateImgBg); p.setBrush(over ? st::msgDateImgBgOver : st::msgDateImgBg);
} }
@ -867,7 +867,7 @@ void LayoutOverviewDocument::paint(Painter &p, const QRect &clip, uint32 selecti
p.setRenderHint(QPainter::HighQualityAntialiasing, false); p.setRenderHint(QPainter::HighQualityAntialiasing, false);
style::sprite icon; style::sprite icon;
if (already || hasdata || _data->loader) { if (loaded || (_data->loadingStarted() && !_data->loader->loadingLocal())) {
icon = (selected ? st::msgFileInCancelSelected : st::msgFileInCancel); icon = (selected ? st::msgFileInCancelSelected : st::msgFileInCancel);
} else { } else {
icon = (selected ? st::msgFileInDownloadSelected : st::msgFileInDownload); icon = (selected ? st::msgFileInDownloadSelected : st::msgFileInDownload);
@ -915,7 +915,7 @@ void LayoutOverviewDocument::paint(Painter &p, const QRect &clip, uint32 selecti
} }
void LayoutOverviewDocument::getState(TextLinkPtr &link, HistoryCursorState &cursor, int32 x, int32 y) const { void LayoutOverviewDocument::getState(TextLinkPtr &link, HistoryCursorState &cursor, int32 x, int32 y) const {
bool already = !_data->already().isEmpty(), hasdata = !_data->data.isEmpty(); bool loaded = _data->loaded() || (_data->loader && _data->loader->localAvailable());
bool showPause = updateStatusText(); bool showPause = updateStatusText();
@ -930,7 +930,7 @@ void LayoutOverviewDocument::getState(TextLinkPtr &link, HistoryCursorState &cur
QRect inner(rtlrect(st::msgFilePadding.left(), st::msgFilePadding.top(), st::msgFileSize, st::msgFileSize, _width)); QRect inner(rtlrect(st::msgFilePadding.left(), st::msgFilePadding.top(), st::msgFileSize, st::msgFileSize, _width));
if (inner.contains(x, y)) { if (inner.contains(x, y)) {
link = (already || hasdata) ? _openl : ((_data->loader || _data->status == FileUploading) ? _cancell : _savel); link = loaded ? _openl : ((_data->loadingStarted() || _data->status == FileUploading) ? _cancell : _savel);
return; return;
} }
} else { } else {
@ -941,12 +941,9 @@ void LayoutOverviewDocument::getState(TextLinkPtr &link, HistoryCursorState &cur
QRect rthumb(rtlrect(0, st::linksBorder + st::msgFileThumbPadding.top(), st::msgFileThumbSize, st::msgFileThumbSize, _width)); QRect rthumb(rtlrect(0, st::linksBorder + st::msgFileThumbPadding.top(), st::msgFileThumbSize, st::msgFileThumbSize, _width));
if (already || hasdata) { if (rthumb.contains(x, y)) {
} else { link = loaded ? _openl : ((_data->loadingStarted() || _data->status == FileUploading) ? _cancell : _savel);
if (rthumb.contains(x, y)) { return;
link = (_data->loader || _data->status == FileUploading) ? _cancell : _savel;
return;
}
} }
if (_data->status != FileUploadFailed) { if (_data->status != FileUploadFailed) {
@ -955,13 +952,13 @@ void LayoutOverviewDocument::getState(TextLinkPtr &link, HistoryCursorState &cur
return; return;
} }
} }
if (!_data->loader && _data->access) { if (!_data->loadingStarted() && _data->access) {
if (rtlrect(0, st::linksBorder, nameleft, _height - st::linksBorder, _width).contains(x, y)) { if (loaded && rtlrect(0, st::linksBorder, nameleft, _height - st::linksBorder, _width).contains(x, y)) {
link = _openl; link = _namel;
return; return;
} }
if (rtlrect(nameleft, nametop, qMin(_width - nameleft - nameright, _namew), st::semiboldFont->height, _width).contains(x, y)) { if (rtlrect(nameleft, nametop, qMin(_width - nameleft - nameright, _namew), st::semiboldFont->height, _width).contains(x, y)) {
link = _openl; link = _namel;
return; return;
} }
} }
@ -975,29 +972,31 @@ bool LayoutOverviewDocument::updateStatusText() const {
statusSize = FileStatusSizeFailed; statusSize = FileStatusSizeFailed;
} else if (_data->status == FileUploading) { } else if (_data->status == FileUploading) {
statusSize = _data->uploadOffset; statusSize = _data->uploadOffset;
} else if (_data->loader) { } else if (_data->loadingStarted()) {
statusSize = _data->loader->currentOffset(); statusSize = _data->loader->currentOffset();
} else if (_data->song() && (!_data->already().isEmpty() || !_data->data.isEmpty())) { } else if (_data->loaded()) {
SongMsgId playing; if (_data->song()) {
AudioPlayerState playingState = AudioPlayerStopped; SongMsgId playing;
int64 playingPosition = 0, playingDuration = 0; AudioPlayerState playingState = AudioPlayerStopped;
int32 playingFrequency = 0; int64 playingPosition = 0, playingDuration = 0;
if (audioPlayer()) { int32 playingFrequency = 0;
audioPlayer()->currentState(&playing, &playingState, &playingPosition, &playingDuration, &playingFrequency); if (audioPlayer()) {
} audioPlayer()->currentState(&playing, &playingState, &playingPosition, &playingDuration, &playingFrequency);
}
if (playing.msgId == _parent->fullId() && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) { if (playing.msgId == _parent->fullId() && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) {
statusSize = -1 - (playingPosition / (playingFrequency ? playingFrequency : AudioVoiceMsgFrequency)); statusSize = -1 - (playingPosition / (playingFrequency ? playingFrequency : AudioVoiceMsgFrequency));
realDuration = playingDuration / (playingFrequency ? playingFrequency : AudioVoiceMsgFrequency); realDuration = playingDuration / (playingFrequency ? playingFrequency : AudioVoiceMsgFrequency);
showPause = (playingState == AudioPlayerPlaying || playingState == AudioPlayerResuming || playingState == AudioPlayerStarting); showPause = (playingState == AudioPlayerPlaying || playingState == AudioPlayerResuming || playingState == AudioPlayerStarting);
} else {
statusSize = FileStatusSizeLoaded;
}
if (!showPause && playing.msgId == _parent->fullId() && App::main() && App::main()->player()->seekingSong(playing)) {
showPause = true;
}
} else { } else {
statusSize = FileStatusSizeLoaded; statusSize = FileStatusSizeLoaded;
} }
if (!showPause && playing.msgId == _parent->fullId() && App::main() && App::main()->player()->seekingSong(playing)) {
showPause = true;
}
} else if (!_data->already().isEmpty() || !_data->data.isEmpty()) {
statusSize = FileStatusSizeLoaded;
} else { } else {
statusSize = FileStatusSizeReady; statusSize = FileStatusSizeReady;
} }

View File

@ -410,7 +410,7 @@ protected:
return !_data->loader; return !_data->loader;
} }
virtual bool dataLoaded() const { virtual bool dataLoaded() const {
return !_data->already().isEmpty() || !_data->data.isEmpty(); return _data->loaded();
} }
virtual bool iconAnimated() const { virtual bool iconAnimated() const {
return _data->song() || !dataLoaded() || (_radial && _radial->animating()); return _data->song() || !dataLoaded() || (_radial && _radial->animating());
@ -419,7 +419,7 @@ protected:
private: private:
OverviewItemInfo _info; OverviewItemInfo _info;
DocumentData *_data; DocumentData *_data;
TextLinkPtr _msgl; TextLinkPtr _msgl, _namel;
QString _name, _date, _ext; QString _name, _date, _ext;
int32 _namew, _datew, _extw; int32 _namew, _datew, _extw;

View File

@ -2411,13 +2411,17 @@ namespace Local {
}; };
TaskId startImageLoad(const StorageKey &location, mtpFileLoader *loader) { TaskId startImageLoad(const StorageKey &location, mtpFileLoader *loader) {
StorageMap::iterator j = _imagesMap.find(location); StorageMap::const_iterator j = _imagesMap.constFind(location);
if (j == _imagesMap.cend() || !_localLoader) { if (j == _imagesMap.cend() || !_localLoader) {
return 0; return 0;
} }
return _localLoader->addTask(new ImageLoadTask(j->first, location, loader)); return _localLoader->addTask(new ImageLoadTask(j->first, location, loader));
} }
bool willImageLoad(const StorageKey &location) {
return (_imagesMap.constFind(location) != _imagesMap.cend());
}
int32 hasImages() { int32 hasImages() {
return _imagesMap.size(); return _imagesMap.size();
} }
@ -2470,13 +2474,17 @@ namespace Local {
}; };
TaskId startStickerImageLoad(const StorageKey &location, mtpFileLoader *loader) { TaskId startStickerImageLoad(const StorageKey &location, mtpFileLoader *loader) {
StorageMap::iterator j = _stickerImagesMap.find(location); StorageMap::const_iterator j = _stickerImagesMap.constFind(location);
if (j == _stickerImagesMap.cend() || !_localLoader) { if (j == _stickerImagesMap.cend() || !_localLoader) {
return 0; return 0;
} }
return _localLoader->addTask(new StickerImageLoadTask(j->first, location, loader)); return _localLoader->addTask(new StickerImageLoadTask(j->first, location, loader));
} }
bool willStickerImageLoad(const StorageKey &location) {
return (_stickerImagesMap.constFind(location) != _stickerImagesMap.cend());
}
int32 hasStickers() { int32 hasStickers() {
return _stickerImagesMap.size(); return _stickerImagesMap.size();
} }
@ -2529,13 +2537,17 @@ namespace Local {
}; };
TaskId startAudioLoad(const StorageKey &location, mtpFileLoader *loader) { TaskId startAudioLoad(const StorageKey &location, mtpFileLoader *loader) {
StorageMap::iterator j = _audiosMap.find(location); StorageMap::const_iterator j = _audiosMap.constFind(location);
if (j == _audiosMap.cend() || !_localLoader) { if (j == _audiosMap.cend() || !_localLoader) {
return 0; return 0;
} }
return _localLoader->addTask(new AudioLoadTask(j->first, location, loader)); return _localLoader->addTask(new AudioLoadTask(j->first, location, loader));
} }
bool willAudioLoad(const StorageKey &location) {
return (_audiosMap.constFind(location) != _audiosMap.cend());
}
int32 hasAudios() { int32 hasAudios() {
return _audiosMap.size(); return _audiosMap.size();
} }

View File

@ -124,16 +124,19 @@ namespace Local {
void writeImage(const StorageKey &location, const ImagePtr &img); void writeImage(const StorageKey &location, const ImagePtr &img);
void writeImage(const StorageKey &location, const StorageImageSaved &jpeg, bool overwrite = true); void writeImage(const StorageKey &location, const StorageImageSaved &jpeg, bool overwrite = true);
TaskId startImageLoad(const StorageKey &location, mtpFileLoader *loader); TaskId startImageLoad(const StorageKey &location, mtpFileLoader *loader);
bool willImageLoad(const StorageKey &location);
int32 hasImages(); int32 hasImages();
qint64 storageImagesSize(); qint64 storageImagesSize();
void writeStickerImage(const StorageKey &location, const QByteArray &data, bool overwrite = true); void writeStickerImage(const StorageKey &location, const QByteArray &data, bool overwrite = true);
TaskId startStickerImageLoad(const StorageKey &location, mtpFileLoader *loader); TaskId startStickerImageLoad(const StorageKey &location, mtpFileLoader *loader);
bool willStickerImageLoad(const StorageKey &location);
int32 hasStickers(); int32 hasStickers();
qint64 storageStickersSize(); qint64 storageStickersSize();
void writeAudio(const StorageKey &location, const QByteArray &data, bool overwrite = true); void writeAudio(const StorageKey &location, const QByteArray &data, bool overwrite = true);
TaskId startAudioLoad(const StorageKey &location, mtpFileLoader *loader); TaskId startAudioLoad(const StorageKey &location, mtpFileLoader *loader);
bool willAudioLoad(const StorageKey &location);
int32 hasAudios(); int32 hasAudios();
qint64 storageAudiosSize(); qint64 storageAudiosSize();

View File

@ -1853,9 +1853,10 @@ void MainWidget::documentLoadProgress(mtpFileLoader *loader) {
QString already = document->already(); QString already = document->already();
HistoryItem *item = (document->openOnSave && document->openOnSaveMsgId.msg) ? App::histItemById(document->openOnSaveMsgId) : 0; HistoryItem *item = (document->openOnSave && document->openOnSaveMsgId.msg) ? App::histItemById(document->openOnSaveMsgId) : 0;
bool play = document->song() && audioPlayer() && document->openOnSave && item; bool playMusic = document->song() && audioPlayer() && document->openOnSave && item;
if ((!already.isEmpty() || (!document->data.isEmpty() && play)) && document->openOnSave) { bool playAnimation = document->isAnimation() && document->openOnSave > 0 && item && item->getMedia();
if (play) { if (document->openOnSave && (!already.isEmpty() || (!document->data.isEmpty() && (playMusic || playAnimation)))) {
if (playMusic) {
SongMsgId playing; SongMsgId playing;
AudioPlayerState playingState = AudioPlayerStopped; AudioPlayerState playingState = AudioPlayerStopped;
audioPlayer()->currentState(&playing, &playingState); audioPlayer()->currentState(&playing, &playingState);
@ -1869,22 +1870,32 @@ void MainWidget::documentLoadProgress(mtpFileLoader *loader) {
songPlayActivated = true; songPlayActivated = true;
} else if (document->openOnSave > 0 && document->size < MediaViewImageSizeLimit) { } else if (document->openOnSave > 0 && document->size < MediaViewImageSizeLimit) {
const FileLocation &location(document->location(true)); if (!document->data.isEmpty() && playAnimation) {
if (location.accessEnable()) {
if (document->openOnSave > 1) { if (document->openOnSave > 1) {
if (!item || !item->getMedia() || !item->getMedia()->playInline(item)) { item->getMedia()->playInline(item);
psOpenFile(already);
}
} else { } else {
if (item && (document->isAnimation() || QImageReader(location.name()).canRead())) { App::wnd()->showDocument(document, item);
App::wnd()->showDocument(document, item);
} else {
psOpenFile(already);
}
} }
location.accessDisable();
} else { } else {
psOpenFile(already); const FileLocation &location(document->location(true));
if (location.accessEnable()) {
if (document->openOnSave > 1) {
if (playAnimation) {
item->getMedia()->playInline(item);
} else {
psOpenFile(already);
}
} else {
if (playAnimation || (item && QImageReader(location.name()).canRead())) {
App::wnd()->showDocument(document, item);
} else {
psOpenFile(already);
}
}
location.accessDisable();
} else {
psOpenFile(already);
}
} }
} else { } else {
QPoint pos(QCursor::pos()); QPoint pos(QCursor::pos());

View File

@ -252,6 +252,11 @@ bool MediaView::gifShown() const {
return false; return false;
} }
void MediaView::stopGif() {
delete _gif;
_gif = 0;
}
void MediaView::documentUpdated(DocumentData *doc) { void MediaView::documentUpdated(DocumentData *doc) {
if (_doc && _doc == doc && !fileShown()) { if (_doc && _doc == doc && !fileShown()) {
if ((_doc->loader && _docCancel.isHidden()) || (!_doc->loader && !_docCancel.isHidden())) { if ((_doc->loader && _docCancel.isHidden()) || (!_doc->loader && !_docCancel.isHidden())) {
@ -314,15 +319,15 @@ void MediaView::updateControls() {
if (!_a_state.animating()) _a_state.start(); if (!_a_state.animating()) _a_state.start();
_a_state.step(); _a_state.step();
} else { } else {
if (_doc->already(true).isEmpty()) { if (_doc->loaded(true)) {
_docDownload.moveToLeft(_docRect.x() + 2 * st::mvDocPadding + st::mvDocIconSize, _docRect.y() + st::mvDocPadding + st::mvDocLinksTop); _docDownload.hide();
_docDownload.show(); _docSaveAs.moveToLeft(_docRect.x() + 2 * st::mvDocPadding + st::mvDocIconSize, _docRect.y() + st::mvDocPadding + st::mvDocLinksTop);
_docSaveAs.moveToLeft(_docRect.x() + 2.5 * st::mvDocPadding + st::mvDocIconSize + _docDownload.width(), _docRect.y() + st::mvDocPadding + st::mvDocLinksTop);
_docSaveAs.show(); _docSaveAs.show();
_docCancel.hide(); _docCancel.hide();
} else { } else {
_docDownload.hide(); _docDownload.moveToLeft(_docRect.x() + 2 * st::mvDocPadding + st::mvDocIconSize, _docRect.y() + st::mvDocPadding + st::mvDocLinksTop);
_docSaveAs.moveToLeft(_docRect.x() + 2 * st::mvDocPadding + st::mvDocIconSize, _docRect.y() + st::mvDocPadding + st::mvDocLinksTop); _docDownload.show();
_docSaveAs.moveToLeft(_docRect.x() + 2.5 * st::mvDocPadding + st::mvDocIconSize + _docDownload.width(), _docRect.y() + st::mvDocPadding + st::mvDocLinksTop);
_docSaveAs.show(); _docSaveAs.show();
_docCancel.hide(); _docCancel.hide();
} }
@ -334,7 +339,7 @@ void MediaView::updateControls() {
_docCancel.hide(); _docCancel.hide();
} }
_saveVisible = ((_photo && _photo->full->loaded()) || (_doc && (!_doc->already(true).isEmpty() || (!fileShown() && (_photo || _doc))))); _saveVisible = ((_photo && _photo->full->loaded()) || (_doc && (_doc->loaded(true) || (!fileShown() && (_photo || _doc)))));
_saveNav = myrtlrect(width() - st::mvIconSize.width() * 2, height() - st::mvIconSize.height(), st::mvIconSize.width(), st::mvIconSize.height()); _saveNav = myrtlrect(width() - st::mvIconSize.width() * 2, height() - st::mvIconSize.height(), st::mvIconSize.width(), st::mvIconSize.height());
_saveNavIcon = centersprite(_saveNav, st::mvSave); _saveNavIcon = centersprite(_saveNav, st::mvSave);
_moreNav = myrtlrect(width() - st::mvIconSize.width(), height() - st::mvIconSize.height(), st::mvIconSize.width(), st::mvIconSize.height()); _moreNav = myrtlrect(width() - st::mvIconSize.width(), height() - st::mvIconSize.height(), st::mvIconSize.width(), st::mvIconSize.height());
@ -445,7 +450,7 @@ void MediaView::step_state(uint64 ms, bool timer) {
if (dt < 1) result = true; if (dt < 1) result = true;
} }
if (_doc && _docRadialStart > 0) { if (_doc && _docRadialStart > 0) {
float64 prg = _doc->loader ? qMax(_doc->loader->currentProgress(), 0.0001) : (_doc->status == FileDownloadFailed ? 0 : (_doc->already().isEmpty() ? 0 : 1)); float64 prg = _doc->loader ? qMax(_doc->loader->currentProgress(), 0.0001) : (_doc->status == FileDownloadFailed ? 0 : (_doc->loaded() ? 1 : 0));
if (prg != a_docRadial.to()) { if (prg != a_docRadial.to()) {
a_docRadial.start(prg); a_docRadial.start(prg);
_docRadialStart = _docRadialLast; _docRadialStart = _docRadialLast;
@ -457,18 +462,22 @@ void MediaView::step_state(uint64 ms, bool timer) {
if (_doc->loader) { if (_doc->loader) {
a_docRadial.update(1. - (st::radialDuration / (st::radialDuration + dt)), anim::linear); a_docRadial.update(1. - (st::radialDuration / (st::radialDuration + dt)), anim::linear);
result = true; result = true;
} else if (dt >= st::radialDuration) { } else if (dt >= st::radialDuration || (_doc->loaded() && _doc->size < MediaViewImageSizeLimit && _doc->isAnimation())) {
a_docRadial.update(1, anim::linear); a_docRadial.update(1, anim::linear);
result = true; result = true;
_docRadialFirst = _docRadialLast = _docRadialStart = 0; _docRadialFirst = _docRadialLast = _docRadialStart = 0;
a_docRadial = anim::fvalue(0, 0); a_docRadial = anim::fvalue(0, 0);
if (!_doc->already().isEmpty() && _doc->size < MediaViewImageSizeLimit) { if (_doc->loaded() && _doc->size < MediaViewImageSizeLimit) {
const FileLocation &location(_doc->location(true)); if (!_doc->data.isEmpty() && _doc->isAnimation()) {
if (location.accessEnable()) { displayDocument(_doc, App::histItemById(_msgmigrated ? 0 : _channel, _msgid));
if (QImageReader(location.name()).canRead()) { } else {
displayDocument(_doc, App::histItemById(_msgmigrated ? 0 : _channel, _msgid)); const FileLocation &location(_doc->location(true));
if (location.accessEnable()) {
if (QImageReader(location.name()).canRead()) {
displayDocument(_doc, App::histItemById(_msgmigrated ? 0 : _channel, _msgid));
}
location.accessDisable();
} }
location.accessDisable();
} }
} }
} else { } else {
@ -547,7 +556,7 @@ void MediaView::onSaveAs() {
QString file; QString file;
if (_doc) { if (_doc) {
const FileLocation &location(_doc->location(true)); const FileLocation &location(_doc->location(true));
if (location.accessEnable()) { if (!_doc->data.isEmpty() || location.accessEnable()) {
QFileInfo alreadyInfo(location.name()); QFileInfo alreadyInfo(location.name());
QDir alreadyDir(alreadyInfo.dir()); QDir alreadyDir(alreadyInfo.dir());
QString name = alreadyInfo.fileName(), filter; QString name = alreadyInfo.fileName(), filter;
@ -568,10 +577,16 @@ void MediaView::onSaveAs() {
file = saveFileName(lang(lng_save_file), filter, qsl("doc"), name, true, alreadyDir); file = saveFileName(lang(lng_save_file), filter, qsl("doc"), name, true, alreadyDir);
psShowOverAll(this); psShowOverAll(this);
if (!file.isEmpty() && file != location.name()) { if (!file.isEmpty() && file != location.name()) {
QFile(location.name()).copy(file); if (_doc->data.isEmpty()) {
QFile(location.name()).copy(file);
} else {
QFile f(file);
f.open(QIODevice::WriteOnly);
f.write(_doc->data);
}
} }
location.accessDisable(); if (_doc->data.isEmpty()) location.accessDisable();
} else { } else {
if (!fileShown()) { if (!fileShown()) {
DocumentSaveLink::doSave(_doc, true); DocumentSaveLink::doSave(_doc, true);
@ -626,8 +641,7 @@ void MediaView::notify_clipReinit(ClipReader *reader) {
} }
displayDocument(_doc, item); displayDocument(_doc, item);
} else { } else {
delete _gif; stopGif();
_gif = 0;
} }
} }
} }
@ -882,10 +896,9 @@ void MediaView::showDocument(DocumentData *doc, HistoryItem *context) {
} }
void MediaView::displayPhoto(PhotoData *photo, HistoryItem *item) { void MediaView::displayPhoto(PhotoData *photo, HistoryItem *item) {
stopGif();
_doc = 0; _doc = 0;
_photo = photo; _photo = photo;
delete _gif;
_gif = 0;
_zoom = 0; _zoom = 0;
@ -939,8 +952,7 @@ void MediaView::displayPhoto(PhotoData *photo, HistoryItem *item) {
void MediaView::displayDocument(DocumentData *doc, HistoryItem *item) { // empty messages shown as docs: doc can be NULL void MediaView::displayDocument(DocumentData *doc, HistoryItem *item) { // empty messages shown as docs: doc can be NULL
if (!doc || !doc->isAnimation() || doc != _doc || (item && (item->id != _msgid || (item->history() != (_msgmigrated ? _migrated : _history))))) { if (!doc || !doc->isAnimation() || doc != _doc || (item && (item->id != _msgid || (item->history() != (_msgmigrated ? _migrated : _history))))) {
delete _gif; stopGif();
_gif = 0;
} }
_doc = doc; _doc = doc;
_photo = 0; _photo = 0;
@ -949,9 +961,21 @@ void MediaView::displayDocument(DocumentData *doc, HistoryItem *item) { // empty
_caption = Text(); _caption = Text();
if (_doc) { if (_doc) {
if (_doc->isAnimation() && !_doc->loaded() && _doc->status == FileReady && _doc->loader && !_doc->loadingStarted()) {
_doc->openOnSave = 0;
_doc->save(QString());
}
const FileLocation &location(_doc->location(true)); const FileLocation &location(_doc->location(true));
if (_doc->sticker() && !_doc->sticker()->img->isNull() && _doc->sticker()->img->loaded()) { if (_doc->sticker() && !_doc->sticker()->img->isNull() && _doc->sticker()->img->loaded()) {
_current = _doc->sticker()->img->pix(); _current = _doc->sticker()->img->pix();
} else if (!_doc->data.isEmpty() && _doc->isAnimation()) {
if (!_gif) {
if (_doc->dimensions.width() && _doc->dimensions.height()) {
_current = _doc->thumb->pixNoCache(_doc->dimensions.width(), _doc->dimensions.height(), true, true, false, _doc->dimensions.width(), _doc->dimensions.height());
}
_gif = new ClipReader(location, _doc->data);
}
} else if (location.accessEnable()) { } else if (location.accessEnable()) {
if (_doc->isAnimation()) { if (_doc->isAnimation()) {
if (!_gif) { if (!_gif) {
@ -1195,7 +1219,7 @@ void MediaView::paintEvent(QPaintEvent *e) {
icon = true; icon = true;
if (!_doc || _doc->thumb->isNull()) { if (!_doc || _doc->thumb->isNull()) {
p.fillRect(_docIconRect, _docIconColor->b); p.fillRect(_docIconRect, _docIconColor->b);
if ((!_doc || !_doc->already().isEmpty()) && (!_docRadialStart || _docRadialOpacity < 1)) { if ((!_doc || _doc->loaded()) && (!_docRadialStart || _docRadialOpacity < 1)) {
p.drawSprite(_docIconRect.topLeft() + QPoint(rtl() ? 0 : (_docIconRect.width() - _docIcon.pxWidth()), 0), _docIcon); p.drawSprite(_docIconRect.topLeft() + QPoint(rtl() ? 0 : (_docIconRect.width() - _docIcon.pxWidth()), 0), _docIcon);
p.setPen(st::mvDocExtColor->p); p.setPen(st::mvDocExtColor->p);
p.setFont(st::mvDocExtFont->f); p.setFont(st::mvDocExtFont->f);
@ -1210,7 +1234,7 @@ void MediaView::paintEvent(QPaintEvent *e) {
float64 o = overLevel(OverIcon); float64 o = overLevel(OverIcon);
if (_doc && _docRadialStart > 0) { if (_doc && _docRadialStart > 0) {
if (_doc->already().isEmpty() && _docRadialOpacity < 1) { if (!_doc->loaded() && _docRadialOpacity < 1) {
p.setOpacity((o * 1. + (1 - o) * st::radialDownloadOpacity) * (1 - _docRadialOpacity)); p.setOpacity((o * 1. + (1 - o) * st::radialDownloadOpacity) * (1 - _docRadialOpacity));
p.drawSpriteCenter(_docIconRect, st::radialDownload); p.drawSpriteCenter(_docIconRect, st::radialDownload);
} }
@ -1236,7 +1260,7 @@ void MediaView::paintEvent(QPaintEvent *e) {
p.setOpacity(1); p.setOpacity(1);
p.setRenderHint(QPainter::HighQualityAntialiasing, false); p.setRenderHint(QPainter::HighQualityAntialiasing, false);
} else if (_doc && _doc->already().isEmpty()) { } else if (_doc && !_doc->loaded()) {
p.setOpacity((o * 1. + (1 - o) * st::radialDownloadOpacity)); p.setOpacity((o * 1. + (1 - o) * st::radialDownloadOpacity));
p.drawSpriteCenter(_docIconRect, st::radialDownload); p.drawSpriteCenter(_docIconRect, st::radialDownload);
} }
@ -1505,8 +1529,7 @@ void MediaView::moveToNext(int32 delta) {
_channel = _history ? _history->channelId() : NoChannel; _channel = _history ? _history->channelId() : NoChannel;
_canForward = _msgid > 0; _canForward = _msgid > 0;
_canDelete = item->canDelete(); _canDelete = item->canDelete();
delete _gif; stopGif();
_gif = 0;
if (HistoryMedia *media = item->getMedia()) { if (HistoryMedia *media = item->getMedia()) {
switch (media->type()) { switch (media->type()) {
case MediaTypePhoto: displayPhoto(static_cast<HistoryPhoto*>(item->getMedia())->photo(), item); preloadData(delta); break; case MediaTypePhoto: displayPhoto(static_cast<HistoryPhoto*>(item->getMedia())->photo(), item); preloadData(delta); break;
@ -1541,31 +1564,6 @@ void MediaView::preloadData(int32 delta) {
int32 from = _index + (delta ? delta : -1), to = _index + (delta ? delta * MediaOverviewPreloadCount : 1); int32 from = _index + (delta ? delta : -1), to = _index + (delta ? delta * MediaOverviewPreloadCount : 1);
if (from > to) qSwap(from, to); if (from > to) qSwap(from, to);
if (_history && _overview != OverviewCount) { if (_history && _overview != OverviewCount) {
for (int32 i = from; i <= to; ++i) {
History *previewHistory = _msgmigrated ? _migrated : _history;
int32 previewIndex = i;
if (_migrated) {
if (_msgmigrated && previewIndex >= _migrated->overview[_overview].size()) {
previewHistory = _history;
previewIndex -= _migrated->overview[_overview].size() + (_history->overviewCount(_overview) - _history->overview[_overview].size());
} else if (!_msgmigrated && previewIndex < 0) {
previewHistory = _migrated;
previewIndex += _migrated->overview[_overview].size();
}
}
if (previewIndex >= 0 && previewIndex < previewHistory->overview[_overview].size() && (previewHistory != (_msgmigrated ? _migrated : _history) || previewIndex != _index)) {
if (HistoryItem *item = App::histItemById(previewHistory->channelId(), previewHistory->overview[_overview][previewIndex])) {
if (HistoryMedia *media = item->getMedia()) {
switch (media->type()) {
case MediaTypePhoto: static_cast<HistoryPhoto*>(media)->photo()->full->load(); break;
case MediaTypeDocument:
case MediaTypeGif: static_cast<HistoryGif*>(media)->getDocument()->thumb->load(); break;
case MediaTypeSticker: static_cast<HistorySticker*>(media)->getDocument()->sticker()->img->load(); break;
}
}
}
}
}
int32 forgetIndex = _index - delta * 2; int32 forgetIndex = _index - delta * 2;
History *forgetHistory = _msgmigrated ? _migrated : _history; History *forgetHistory = _msgmigrated ? _migrated : _history;
if (_migrated) { if (_migrated) {
@ -1584,7 +1582,47 @@ void MediaView::preloadData(int32 delta) {
case MediaTypePhoto: static_cast<HistoryPhoto*>(media)->photo()->forget(); break; case MediaTypePhoto: static_cast<HistoryPhoto*>(media)->photo()->forget(); break;
case MediaTypeDocument: case MediaTypeDocument:
case MediaTypeGif: case MediaTypeGif:
case MediaTypeSticker: media->getDocument()->forget(); break; case MediaTypeSticker:
DocumentData *doc = media->getDocument();
doc->forget();
if (!doc->data.isEmpty()) {
doc->data.clear();
doc->prepareAutoLoader();
}
break;
}
}
}
}
for (int32 i = from; i <= to; ++i) {
History *previewHistory = _msgmigrated ? _migrated : _history;
int32 previewIndex = i;
if (_migrated) {
if (_msgmigrated && previewIndex >= _migrated->overview[_overview].size()) {
previewHistory = _history;
previewIndex -= _migrated->overview[_overview].size() + (_history->overviewCount(_overview) - _history->overview[_overview].size());
} else if (!_msgmigrated && previewIndex < 0) {
previewHistory = _migrated;
previewIndex += _migrated->overview[_overview].size();
}
}
if (previewIndex >= 0 && previewIndex < previewHistory->overview[_overview].size() && (previewHistory != (_msgmigrated ? _migrated : _history) || previewIndex != _index)) {
if (HistoryItem *item = App::histItemById(previewHistory->channelId(), previewHistory->overview[_overview][previewIndex])) {
if (HistoryMedia *media = item->getMedia()) {
switch (media->type()) {
case MediaTypePhoto: static_cast<HistoryPhoto*>(media)->photo()->full->load(); break;
case MediaTypeDocument:
case MediaTypeGif: {
DocumentData *doc = media->getDocument();
doc->thumb->load();
if (doc->isAnimation() && !doc->loaded() && doc->status == FileReady && doc->loader && !doc->loadingStarted()) {
doc->openOnSave = 0;
doc->save(QString());
}
} break;
case MediaTypeSticker: media->getDocument()->sticker()->img->load(); break;
}
} }
} }
} }
@ -1950,8 +1988,7 @@ void MediaView::hide() {
_controlsState = ControlsShown; _controlsState = ControlsShown;
a_cOpacity = anim::fvalue(1, 1); a_cOpacity = anim::fvalue(1, 1);
QWidget::hide(); QWidget::hide();
delete _gif; stopGif();
_gif = 0;
} }
void MediaView::onMenuDestroy(QObject *obj) { void MediaView::onMenuDestroy(QObject *obj) {

View File

@ -146,6 +146,7 @@ private:
bool fileShown() const; bool fileShown() const;
bool gifShown() const; bool gifShown() const;
void stopGif();
style::sprite _docIcon; style::sprite _docIcon;
style::color _docIconColor; style::color _docIconColor;

View File

@ -47,11 +47,28 @@ namespace {
LoaderQueues queues; LoaderQueues queues;
} }
mtpFileLoader::mtpFileLoader(int32 dc, const uint64 &volume, int32 local, const uint64 &secret, int32 size) : prev(0), next(0), mtpFileLoader::mtpFileLoader(int32 dc, const uint64 &volume, int32 local, const uint64 &secret, int32 size)
priority(0), _paused(false), inQueue(false), complete(false), : prev(0)
_localStatus(LocalNotTried), skippedBytes(0), nextRequestOffset(0), lastComplete(false), , next(0)
dc(dc), _locationType(UnknownFileLocation), volume(volume), local(local), secret(secret), , priority(0)
id(0), access(0), fileIsOpen(false), size(size), type(mtpc_storage_fileUnknown), _localTaskId(0) { , _paused(false)
, inQueue(false)
, complete(false)
, _localStatus(LocalNotTried)
, skippedBytes(0)
, nextRequestOffset(0)
, lastComplete(false)
, dc(dc)
, _locationType(UnknownFileLocation)
, volume(volume)
, local(local)
, secret(secret)
, id(0)
, access(0)
, fileIsOpen(false)
, size(size)
, type(mtpc_storage_fileUnknown)
, _localTaskId(0) {
LoaderQueues::iterator i = queues.find(dc); LoaderQueues::iterator i = queues.find(dc);
if (i == queues.cend()) { if (i == queues.cend()) {
i = queues.insert(dc, mtpFileLoaderQueue()); i = queues.insert(dc, mtpFileLoaderQueue());
@ -59,11 +76,31 @@ id(0), access(0), fileIsOpen(false), size(size), type(mtpc_storage_fileUnknown),
queue = &i.value(); queue = &i.value();
} }
mtpFileLoader::mtpFileLoader(int32 dc, const uint64 &id, const uint64 &access, LocationType type, const QString &to, int32 size, bool todata) : prev(0), next(0), mtpFileLoader::mtpFileLoader(int32 dc, const uint64 &id, const uint64 &access, LocationType type, const QString &to, int32 size, bool todata)
priority(0), _paused(false), inQueue(false), complete(false), : prev(0)
_localStatus(LocalNotTried), skippedBytes(0), nextRequestOffset(0), lastComplete(false), , next(0)
dc(dc), _locationType(type), volume(0), local(0), secret(0), , priority(0)
id(id), access(access), file(to), fname(to), fileIsOpen(false), duplicateInData(todata), size(size), type(mtpc_storage_fileUnknown), _localTaskId(0) { , _paused(false)
, inQueue(false)
, complete(false)
, _localStatus(LocalNotTried)
, skippedBytes(0)
, nextRequestOffset(0)
, lastComplete(false)
, dc(dc)
, _locationType(type)
, volume(0)
, local(0)
, secret(0)
, id(id)
, access(access)
, file(to)
, fname(to)
, fileIsOpen(false)
, duplicateInData(todata)
, size(size)
, type(mtpc_storage_fileUnknown)
, _localTaskId(0) {
LoaderQueues::iterator i = queues.find(MTP::dld[0] + dc); LoaderQueues::iterator i = queues.find(MTP::dld[0] + dc);
if (i == queues.cend()) { if (i == queues.cend()) {
i = queues.insert(MTP::dld[0] + dc, mtpFileLoaderQueue()); i = queues.insert(MTP::dld[0] + dc, mtpFileLoaderQueue());
@ -411,8 +448,30 @@ void mtpFileLoader::localLoaded(const StorageImageSaved &result, const QByteArra
loadNext(); loadNext();
} }
bool mtpFileLoader::tryingLocal() const { bool mtpFileLoader::localAvailable() const {
return (_localStatus == LocalLoading); if (_localStatus == LocalLoading || _localStatus == LocalLoaded || _localStatus == LocalNeedsTry) {
return true;
}
if (_localStatus == LocalNotFound || _localStatus == LocalFailed) {
return false;
}
bool result = false;
if (_locationType == UnknownFileLocation) {
result = Local::willImageLoad(storageKey(dc, volume, local));
} else {
if (duplicateInData) {
MediaKey mkey = mediaKey(_locationType, dc, id);
if (_locationType == DocumentFileLocation) {
result = Local::willStickerImageLoad(mkey);
} else if (_locationType == AudioFileLocation) {
result = Local::willAudioLoad(mkey);
}
}
}
_localStatus = result ? LocalNeedsTry : LocalNotFound;
return result;
} }
void mtpFileLoader::start(bool loadFirst, bool prior) { void mtpFileLoader::start(bool loadFirst, bool prior) {
@ -432,10 +491,10 @@ void mtpFileLoader::start(bool loadFirst, bool prior) {
if (prior) { if (prior) {
if (inQueue && priority == _priority) { if (inQueue && priority == _priority) {
if (loadFirst) { if (loadFirst) {
if (!prev) return started(loadFirst, prior); if (!prev) return startLoading(loadFirst, prior);
before = queue->start; before = queue->start;
} else { } else {
if (!next || next->priority < _priority) return started(loadFirst, prior); if (!next || next->priority < _priority) return startLoading(loadFirst, prior);
after = next; after = next;
while (after->next && after->next->priority == _priority) { while (after->next && after->next->priority == _priority) {
after = after->next; after = after->next;
@ -444,7 +503,7 @@ void mtpFileLoader::start(bool loadFirst, bool prior) {
} else { } else {
priority = _priority; priority = _priority;
if (loadFirst) { if (loadFirst) {
if (inQueue && !prev) return started(loadFirst, prior); if (inQueue && !prev) return startLoading(loadFirst, prior);
before = queue->start; before = queue->start;
} else { } else {
if (inQueue) { if (inQueue) {
@ -456,7 +515,7 @@ void mtpFileLoader::start(bool loadFirst, bool prior) {
before = before->prev; before = before->prev;
} }
} else { } else {
return started(loadFirst, prior); return startLoading(loadFirst, prior);
} }
} else { } else {
if (queue->start && queue->start->priority == _priority) { if (queue->start && queue->start->priority == _priority) {
@ -474,13 +533,13 @@ void mtpFileLoader::start(bool loadFirst, bool prior) {
} }
} else { } else {
if (loadFirst) { if (loadFirst) {
if (inQueue && (!prev || prev->priority == _priority)) return started(loadFirst, prior); if (inQueue && (!prev || prev->priority == _priority)) return startLoading(loadFirst, prior);
before = prev; before = prev;
while (before->prev && before->prev->priority != _priority) { while (before->prev && before->prev->priority != _priority) {
before = before->prev; before = before->prev;
} }
} else { } else {
if (inQueue && !next) return started(loadFirst, prior); if (inQueue && !next) return startLoading(loadFirst, prior);
after = queue->end; after = queue->end;
} }
} }
@ -513,7 +572,7 @@ void mtpFileLoader::start(bool loadFirst, bool prior) {
} else { } else {
LOG(("Queue Error: _start && !before && !after")); LOG(("Queue Error: _start && !before && !after"));
} }
return started(loadFirst, prior); return startLoading(loadFirst, prior);
} }
void mtpFileLoader::cancel() { void mtpFileLoader::cancel() {
@ -549,15 +608,7 @@ void mtpFileLoader::cancelRequests() {
} }
} }
bool mtpFileLoader::loading() const { void mtpFileLoader::startLoading(bool loadFirst, bool prior) {
return inQueue;
}
bool mtpFileLoader::paused() const {
return _paused;
}
void mtpFileLoader::started(bool loadFirst, bool prior) {
if ((queue->queries >= MaxFileQueries && (!loadFirst || !prior)) || complete) return; if ((queue->queries >= MaxFileQueries && (!loadFirst || !prior)) || complete) return;
loadPart(); loadPart();
} }

View File

@ -100,6 +100,7 @@ struct StorageImageSaved {
enum LocalLoadStatus { enum LocalLoadStatus {
LocalNotTried, LocalNotTried,
LocalNeedsTry,
LocalNotFound, LocalNotFound,
LocalLoading, LocalLoading,
LocalLoaded, LocalLoaded,
@ -139,9 +140,24 @@ public:
void pause(); void pause();
void start(bool loadFirst = false, bool prior = true); void start(bool loadFirst = false, bool prior = true);
void cancel(); void cancel();
bool loading() const;
bool paused() const; bool loading() const {
bool tryingLocal() const; return inQueue;
}
bool paused() const {
return _paused;
}
bool started() const {
return inQueue || _paused;
}
bool loadingLocal() const {
return (_localStatus == LocalLoading);
}
bool localAvailable() const;
uint64 objId() const; uint64 objId() const;
@ -161,7 +177,7 @@ private:
mtpFileLoaderQueue *queue; mtpFileLoaderQueue *queue;
bool _paused, inQueue, complete; bool _paused, inQueue, complete;
LocalLoadStatus _localStatus; mutable LocalLoadStatus _localStatus;
bool tryLoadLocal(); bool tryLoadLocal();
void cancelRequests(); void cancelRequests();
@ -172,7 +188,7 @@ private:
int32 nextRequestOffset; int32 nextRequestOffset;
bool lastComplete; bool lastComplete;
void started(bool loadFirst, bool prior); void startLoading(bool loadFirst, bool prior);
void removeFromQueue(); void removeFromQueue();
void loadNext(); void loadNext();

View File

@ -1271,7 +1271,7 @@ void OverviewInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
if (lnkPhoto) { if (lnkPhoto) {
_menu->addAction(lang(lng_context_open_image), this, SLOT(openContextUrl()))->setEnabled(true); _menu->addAction(lang(lng_context_open_image), this, SLOT(openContextUrl()))->setEnabled(true);
} else { } else {
if ((lnkVideo && lnkVideo->video()->loader) || (lnkAudio && lnkAudio->audio()->loader) || (lnkDocument && lnkDocument->document()->loader)) { if ((lnkVideo && lnkVideo->video()->loader) || (lnkAudio && lnkAudio->audio()->loadingStarted()) || (lnkDocument && lnkDocument->document()->loadingStarted())) {
_menu->addAction(lang(lng_context_cancel_download), this, SLOT(cancelContextDownload()))->setEnabled(true); _menu->addAction(lang(lng_context_cancel_download), this, SLOT(cancelContextDownload()))->setEnabled(true);
} else { } else {
if ((lnkVideo && !lnkVideo->video()->already(true).isEmpty()) || (lnkAudio && !lnkAudio->audio()->already(true).isEmpty()) || (lnkDocument && !lnkDocument->document()->already(true).isEmpty())) { if ((lnkVideo && !lnkVideo->video()->already(true).isEmpty()) || (lnkAudio && !lnkAudio->audio()->already(true).isEmpty()) || (lnkDocument && !lnkDocument->document()->already(true).isEmpty())) {
@ -1526,12 +1526,15 @@ void OverviewInner::saveContextFile() {
} }
void OverviewInner::openContextFile() { void OverviewInner::openContextFile() {
HistoryItem *was = App::hoveredLinkItem();
App::hoveredLinkItem(App::contextItem());
VideoLink *lnkVideo = dynamic_cast<VideoLink*>(_contextMenuLnk.data()); VideoLink *lnkVideo = dynamic_cast<VideoLink*>(_contextMenuLnk.data());
AudioLink *lnkAudio = dynamic_cast<AudioLink*>(_contextMenuLnk.data()); AudioLink *lnkAudio = dynamic_cast<AudioLink*>(_contextMenuLnk.data());
DocumentLink *lnkDocument = dynamic_cast<DocumentLink*>(_contextMenuLnk.data()); DocumentLink *lnkDocument = dynamic_cast<DocumentLink*>(_contextMenuLnk.data());
if (lnkVideo) VideoOpenLink(lnkVideo->video()).onClick(Qt::LeftButton); if (lnkVideo) VideoOpenLink(lnkVideo->video()).onClick(Qt::LeftButton);
if (lnkAudio) AudioOpenLink(lnkAudio->audio()).onClick(Qt::LeftButton); if (lnkAudio) AudioOpenLink(lnkAudio->audio()).onClick(Qt::LeftButton);
if (lnkDocument) DocumentOpenLink(lnkDocument->document()).onClick(Qt::LeftButton); if (lnkDocument) DocumentOpenLink(lnkDocument->document()).onClick(Qt::LeftButton);
App::hoveredLinkItem(was);
} }
bool OverviewInner::onSearchMessages(bool searchCache) { bool OverviewInner::onSearchMessages(bool searchCache) {

View File

@ -775,6 +775,13 @@ void AudioOpenLink::onClick(Qt::MouseButton button) const {
if (data->status != FileReady) return; if (data->status != FileReady) return;
if (data->loader && !data->loader->started()) {
data->openOnSave = 1;
data->openOnSaveMsgId = App::hoveredLinkItem() ? App::hoveredLinkItem()->fullId() : (App::contextItem() ? App::contextItem()->fullId() : FullMsgId());
data->save(QString());
return;
}
bool mp3 = (data->mime == qstr("audio/mp3")); bool mp3 = (data->mime == qstr("audio/mp3"));
QString filename = saveFileName(lang(lng_save_audio), mp3 ? qsl("MP3 Audio (*.mp3);;All files (*.*)") : qsl("OGG Opus Audio (*.ogg);;All files (*.*)"), qsl("audio"), mp3 ? qsl(".mp3") : qsl(".ogg"), false); QString filename = saveFileName(lang(lng_save_audio), mp3 ? qsl("MP3 Audio (*.mp3);;All files (*.*)") : qsl("OGG Opus Audio (*.ogg);;All files (*.*)"), qsl("audio"), mp3 ? qsl(".mp3") : qsl(".ogg"), false);
if (!filename.isEmpty()) { if (!filename.isEmpty()) {
@ -885,10 +892,11 @@ const FileLocation &AudioData::location(bool check) {
void DocumentOpenLink::doOpen(DocumentData *data, int32 openOnSave) { void DocumentOpenLink::doOpen(DocumentData *data, int32 openOnSave) {
if (!data->date) return; if (!data->date) return;
bool play = data->song() && App::hoveredLinkItem() && audioPlayer(); bool playMusic = data->song() && audioPlayer() && App::hoveredLinkItem();
bool playAnimation = data->isAnimation() && App::hoveredLinkItem() && App::hoveredLinkItem()->getMedia();
const FileLocation &location(data->location(true)); const FileLocation &location(data->location(true));
if (!location.isEmpty() || (!data->data.isEmpty() && play)) { if (!location.isEmpty() || (!data->data.isEmpty() && (playMusic || playAnimation))) {
if (play) { if (playMusic) {
SongMsgId playing; SongMsgId playing;
AudioPlayerState playingState = AudioPlayerStopped; AudioPlayerState playingState = AudioPlayerStopped;
audioPlayer()->currentState(&playing, &playingState); audioPlayer()->currentState(&playing, &playingState);
@ -899,13 +907,23 @@ void DocumentOpenLink::doOpen(DocumentData *data, int32 openOnSave) {
audioPlayer()->play(song); audioPlayer()->play(song);
if (App::main()) App::main()->documentPlayProgress(song); if (App::main()) App::main()->documentPlayProgress(song);
} }
} else if (data->size < MediaViewImageSizeLimit && location.accessEnable()) { } else if (data->size < MediaViewImageSizeLimit) {
if ((App::hoveredLinkItem() || App::contextItem()) && (data->isAnimation() || QImageReader(location.name()).canRead())) { if (!data->data.isEmpty() && playAnimation) {
App::wnd()->showDocument(data, App::hoveredLinkItem() ? App::hoveredLinkItem() : App::contextItem()); if (openOnSave > 1) {
App::hoveredLinkItem()->getMedia()->playInline(App::hoveredLinkItem());
} else {
App::wnd()->showDocument(data, App::hoveredLinkItem());
}
} else if (location.accessEnable()) {
if ((App::hoveredLinkItem() || App::contextItem()) && (data->isAnimation() || QImageReader(location.name()).canRead())) {
App::wnd()->showDocument(data, App::hoveredLinkItem() ? App::hoveredLinkItem() : App::contextItem());
} else {
psOpenFile(location.name());
}
location.accessDisable();
} else { } else {
psOpenFile(location.name()); psOpenFile(location.name());
} }
location.accessDisable();
} else { } else {
psOpenFile(location.name()); psOpenFile(location.name());
} }
@ -914,6 +932,13 @@ void DocumentOpenLink::doOpen(DocumentData *data, int32 openOnSave) {
if (data->status != FileReady) return; if (data->status != FileReady) return;
if (data->loader && !data->loader->started()) {
data->openOnSave = openOnSave;
data->openOnSaveMsgId = App::hoveredLinkItem() ? App::hoveredLinkItem()->fullId() : (App::contextItem() ? App::contextItem()->fullId() : FullMsgId());
data->save(QString());
return;
}
QString name = data->name, filter; QString name = data->name, filter;
MimeType mimeType = mimeTypeForName(data->mime); MimeType mimeType = mimeTypeForName(data->mime);
QStringList p = mimeType.globPatterns(); QStringList p = mimeType.globPatterns();

View File

@ -945,6 +945,9 @@ struct AudioData {
bool loaded(bool check = false) { bool loaded(bool check = false) {
return !data.isEmpty() || !already(check).isEmpty(); return !data.isEmpty() || !already(check).isEmpty();
} }
bool loadingStarted() {
return loader && loader->started();
}
float64 progress() const { float64 progress() const {
return loader ? loader->currentProgress() : ((status == FileDownloadFailed || (_location.name().isEmpty() && data.isEmpty())) ? 0 : 1); return loader ? loader->currentProgress() : ((status == FileDownloadFailed || (_location.name().isEmpty() && data.isEmpty())) ? 0 : 1);
@ -1141,6 +1144,9 @@ struct DocumentData {
bool loaded(bool check = false) { bool loaded(bool check = false) {
return !data.isEmpty() || !already(check).isEmpty(); return !data.isEmpty() || !already(check).isEmpty();
} }
bool loadingStarted() {
return loader && loader->started();
}
void prepareAutoLoader(); void prepareAutoLoader();
StickerData *sticker() { StickerData *sticker() {
return (type == StickerDocument) ? static_cast<StickerData*>(_additional) : 0; return (type == StickerDocument) ? static_cast<StickerData*>(_additional) : 0;

View File

@ -777,21 +777,21 @@ void Window::showPhoto(const PhotoLink *lnk, HistoryItem *item) {
} }
void Window::showPhoto(PhotoData *photo, HistoryItem *item) { void Window::showPhoto(PhotoData *photo, HistoryItem *item) {
Ui::hideLayer(true); if (_mediaView->isHidden()) Ui::hideLayer(true);
_mediaView->showPhoto(photo, item); _mediaView->showPhoto(photo, item);
_mediaView->activateWindow(); _mediaView->activateWindow();
_mediaView->setFocus(); _mediaView->setFocus();
} }
void Window::showPhoto(PhotoData *photo, PeerData *peer) { void Window::showPhoto(PhotoData *photo, PeerData *peer) {
Ui::hideLayer(true); if (_mediaView->isHidden()) Ui::hideLayer(true);
_mediaView->showPhoto(photo, peer); _mediaView->showPhoto(photo, peer);
_mediaView->activateWindow(); _mediaView->activateWindow();
_mediaView->setFocus(); _mediaView->setFocus();
} }
void Window::showDocument(DocumentData *doc, HistoryItem *item) { void Window::showDocument(DocumentData *doc, HistoryItem *item) {
Ui::hideLayer(true); if (_mediaView->isHidden()) Ui::hideLayer(true);
_mediaView->showDocument(doc, item); _mediaView->showDocument(doc, item);
_mediaView->activateWindow(); _mediaView->activateWindow();
_mediaView->setFocus(); _mediaView->setFocus();