From dd1d04e9b01b09266a45a368ade2197bf7c1ddbf Mon Sep 17 00:00:00 2001 From: John Preston Date: Sun, 10 Apr 2016 22:18:26 +0400 Subject: [PATCH] Inline bot results preview: photo, audio, file, voice. Beta 9040126. --- Telegram/SourceFiles/app.cpp | 10 +- Telegram/SourceFiles/boxes/stickersetbox.cpp | 4 +- Telegram/SourceFiles/config.h | 2 +- Telegram/SourceFiles/dropdown.cpp | 42 +++- Telegram/SourceFiles/dropdown.h | 2 + Telegram/SourceFiles/facades.cpp | 18 +- Telegram/SourceFiles/facades.h | 6 +- Telegram/SourceFiles/history.cpp | 6 +- Telegram/SourceFiles/historywidget.cpp | 4 + Telegram/SourceFiles/historywidget.h | 1 + .../inline_bot_layout_internal.cpp | 185 +++++++++++++----- .../inline_bots/inline_bot_layout_internal.h | 22 ++- .../inline_bots/inline_bot_layout_item.cpp | 40 ++++ .../inline_bots/inline_bot_layout_item.h | 15 +- .../inline_bots/inline_bot_result.cpp | 16 +- Telegram/SourceFiles/layerwidget.cpp | 179 +++++++++++------ Telegram/SourceFiles/layerwidget.h | 19 +- Telegram/SourceFiles/layout.cpp | 6 +- Telegram/SourceFiles/layout.h | 1 - Telegram/SourceFiles/mainwidget.cpp | 23 ++- Telegram/SourceFiles/mainwidget.h | 1 + Telegram/SourceFiles/mediaview.cpp | 12 +- Telegram/SourceFiles/overviewwidget.cpp | 2 +- Telegram/SourceFiles/playerwidget.cpp | 23 ++- Telegram/SourceFiles/structs.cpp | 53 +++-- Telegram/SourceFiles/structs.h | 29 +-- Telegram/SourceFiles/ui/images.cpp | 24 ++- Telegram/SourceFiles/ui/images.h | 6 + Telegram/SourceFiles/window.cpp | 57 +++--- Telegram/SourceFiles/window.h | 37 ++-- Telegram/Telegram.rc | 8 +- Telegram/Version | 2 +- 32 files changed, 597 insertions(+), 258 deletions(-) diff --git a/Telegram/SourceFiles/app.cpp b/Telegram/SourceFiles/app.cpp index df07ddfcd..c07ee3f82 100644 --- a/Telegram/SourceFiles/app.cpp +++ b/Telegram/SourceFiles/app.cpp @@ -1736,14 +1736,16 @@ namespace { } HistoryItem *histItemById(ChannelId channelId, MsgId itemId) { - MsgsData *data = fetchMsgsData(channelId, false); - if (!data) return 0; + if (!itemId) return nullptr; - MsgsData::const_iterator i = data->constFind(itemId); + MsgsData *data = fetchMsgsData(channelId, false); + if (!data) return nullptr; + + auto i = data->constFind(itemId); if (i != data->cend()) { return i.value(); } - return 0; + return nullptr; } void historyRegItem(HistoryItem *item) { diff --git a/Telegram/SourceFiles/boxes/stickersetbox.cpp b/Telegram/SourceFiles/boxes/stickersetbox.cpp index 03fe04bfc..2756b15bc 100644 --- a/Telegram/SourceFiles/boxes/stickersetbox.cpp +++ b/Telegram/SourceFiles/boxes/stickersetbox.cpp @@ -171,7 +171,7 @@ void StickerSetInner::mouseMoveEvent(QMouseEvent *e) { int32 index = stickerFromGlobalPos(e->globalPos()); if (index >= 0 && index < _pack.size() && index != _previewShown) { _previewShown = index; - Ui::showStickerPreview(_pack.at(_previewShown)); + Ui::showMediaPreview(_pack.at(_previewShown)); } } } @@ -184,7 +184,7 @@ void StickerSetInner::onPreview() { int32 index = stickerFromGlobalPos(QCursor::pos()); if (index >= 0 && index < _pack.size()) { _previewShown = index; - Ui::showStickerPreview(_pack.at(_previewShown)); + Ui::showMediaPreview(_pack.at(_previewShown)); } } diff --git a/Telegram/SourceFiles/config.h b/Telegram/SourceFiles/config.h index 1658ba1e1..a7f66be4e 100644 --- a/Telegram/SourceFiles/config.h +++ b/Telegram/SourceFiles/config.h @@ -23,7 +23,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org static const int32 AppVersion = 9040; static const wchar_t *AppVersionStr = L"0.9.40"; static const bool DevVersion = false; -#define BETA_VERSION (9040124ULL) // just comment this line to build public version +#define BETA_VERSION (9040126ULL) // just comment this line to build public version static const wchar_t *AppNameOld = L"Telegram Win (Unofficial)"; static const wchar_t *AppName = L"Telegram Desktop"; diff --git a/Telegram/SourceFiles/dropdown.cpp b/Telegram/SourceFiles/dropdown.cpp index c24fbedc5..53d1460b2 100644 --- a/Telegram/SourceFiles/dropdown.cpp +++ b/Telegram/SourceFiles/dropdown.cpp @@ -2046,6 +2046,19 @@ int32 StickerPanInner::validateExistingInlineRows(const InlineResults &results) return until; } +void StickerPanInner::notify_inlineItemLayoutChanged(const InlineItem *layout) { + if (_selected < 0 || !_showingInlineItems) { + return; + } + + int32 row = _selected / MatrixRowShift, col = _selected % MatrixRowShift; + if (row < _inlineRows.size() && col < _inlineRows.at(row).items.size()) { + if (layout == _inlineRows.at(row).items.at(col)) { + updateSelected(); + } + } +} + void StickerPanInner::ui_repaintInlineItem(const InlineItem *layout) { uint64 ms = getms(); if (_lastScrolled + 100 <= ms) { @@ -2279,8 +2292,11 @@ void StickerPanInner::updateSelected() { if (_pressedSel >= 0 && _selected >= 0 && _pressedSel != _selected) { _pressedSel = _selected; if (row >= 0 && col >= 0) { - if (DocumentData *previewDocument = _inlineRows.at(row).items.at(col)->getPreviewDocument()) { - Ui::showStickerPreview(previewDocument); + auto layout = _inlineRows.at(row).items.at(col); + if (auto previewDocument = layout->getPreviewDocument()) { + Ui::showMediaPreview(previewDocument); + } else if (auto previewPhoto = layout->getPreviewPhoto()) { + Ui::showMediaPreview(previewPhoto); } } } @@ -2366,7 +2382,7 @@ void StickerPanInner::updateSelected() { if (_pressedSel >= 0 && _selected >= 0 && _pressedSel != _selected) { _pressedSel = _selected; if (newSel >= 0 && xNewSel < 0) { - Ui::showStickerPreview(_sets.at(newSelTab).pack.at(newSel % MatrixRowShift)); + Ui::showMediaPreview(_sets.at(newSelTab).pack.at(newSel % MatrixRowShift)); } } if (startanim && !_a_selected.animating()) _a_selected.start(); @@ -2381,15 +2397,19 @@ void StickerPanInner::onPreview() { if (_showingInlineItems) { int32 row = _pressedSel / MatrixRowShift, col = _pressedSel % MatrixRowShift; if (row < _inlineRows.size() && col < _inlineRows.at(row).items.size()) { - if (DocumentData *previewDocument = _inlineRows.at(row).items.at(col)->getPreviewDocument()) { - Ui::showStickerPreview(previewDocument); + auto layout = _inlineRows.at(row).items.at(col); + if (auto previewDocument = layout->getPreviewDocument()) { + Ui::showMediaPreview(previewDocument); + _previewShown = true; + } else if (auto previewPhoto = layout->getPreviewPhoto()) { + Ui::showMediaPreview(previewPhoto); _previewShown = true; } } } else if (_pressedSel < MatrixRowShift * _sets.size()) { int tab = (_pressedSel / MatrixRowShift), sel = _pressedSel % MatrixRowShift; if (sel < _sets.at(tab).pack.size()) { - Ui::showStickerPreview(_sets.at(tab).pack.at(sel)); + Ui::showMediaPreview(_sets.at(tab).pack.at(sel)); _previewShown = true; } } @@ -3392,6 +3412,12 @@ void EmojiPan::stickersInstalled(uint64 setId) { showStart(); } +void EmojiPan::notify_inlineItemLayoutChanged(const InlineBots::Layout::ItemBase *layout) { + if (_stickersShown && !isHidden()) { + s_inner.notify_inlineItemLayoutChanged(layout); + } +} + void EmojiPan::ui_repaintInlineItem(const InlineBots::Layout::ItemBase *layout) { if (_stickersShown && !isHidden()) { s_inner.ui_repaintInlineItem(layout); @@ -4233,7 +4259,7 @@ void MentionsInner::onUpdateSelected(bool force) { if (_down >= 0 && _sel >= 0 && _down != _sel) { _down = _sel; if (_down >= 0 && _down < _srows->size()) { - Ui::showStickerPreview(_srows->at(_down)); + Ui::showMediaPreview(_srows->at(_down)); } } } @@ -4249,7 +4275,7 @@ void MentionsInner::onParentGeometryChanged() { void MentionsInner::onPreview() { if (_down >= 0 && _down < _srows->size()) { - Ui::showStickerPreview(_srows->at(_down)); + Ui::showMediaPreview(_srows->at(_down)); _previewShown = true; } } diff --git a/Telegram/SourceFiles/dropdown.h b/Telegram/SourceFiles/dropdown.h index 492d04760..10c51449b 100644 --- a/Telegram/SourceFiles/dropdown.h +++ b/Telegram/SourceFiles/dropdown.h @@ -383,6 +383,7 @@ public: uint64 currentSet(int yOffset) const; + void notify_inlineItemLayoutChanged(const InlineItem *layout); void ui_repaintInlineItem(const InlineItem *layout); bool ui_isInlineItemVisible(const InlineItem *layout); bool ui_isInlineItemBeingChosen(); @@ -607,6 +608,7 @@ public: ).contains(QRect(mapFromGlobal(globalRect.topLeft()), globalRect.size())); } + void notify_inlineItemLayoutChanged(const InlineBots::Layout::ItemBase *layout); void ui_repaintInlineItem(const InlineBots::Layout::ItemBase *layout); bool ui_isInlineItemVisible(const InlineBots::Layout::ItemBase *layout); bool ui_isInlineItemBeingChosen(); diff --git a/Telegram/SourceFiles/facades.cpp b/Telegram/SourceFiles/facades.cpp index c50d34a2c..396505f70 100644 --- a/Telegram/SourceFiles/facades.cpp +++ b/Telegram/SourceFiles/facades.cpp @@ -149,15 +149,21 @@ namespace App { namespace Ui { - void showStickerPreview(DocumentData *sticker) { + void showMediaPreview(DocumentData *document) { if (Window *w = App::wnd()) { - w->ui_showStickerPreview(sticker); + w->ui_showMediaPreview(document); } } - void hideStickerPreview() { + void showMediaPreview(PhotoData *photo) { if (Window *w = App::wnd()) { - w->ui_hideStickerPreview(); + w->ui_showMediaPreview(photo); + } + } + + void hideMediaPreview() { + if (Window *w = App::wnd()) { + w->ui_hideMediaPreview(); } } @@ -292,6 +298,10 @@ namespace Notify { if (MainWidget *m = App::main()) m->notify_historyItemLayoutChanged(item); } + void inlineItemLayoutChanged(const InlineBots::Layout::ItemBase *layout) { + if (MainWidget *m = App::main()) m->notify_inlineItemLayoutChanged(layout); + } + void handlePendingHistoryUpdate() { if (MainWidget *m = App::main()) { m->notify_handlePendingHistoryUpdate(); diff --git a/Telegram/SourceFiles/facades.h b/Telegram/SourceFiles/facades.h index a8e3631e9..87461d585 100644 --- a/Telegram/SourceFiles/facades.h +++ b/Telegram/SourceFiles/facades.h @@ -52,8 +52,9 @@ class ItemBase; namespace Ui { - void showStickerPreview(DocumentData *sticker); - void hideStickerPreview(); + void showMediaPreview(DocumentData *document); + void showMediaPreview(PhotoData *photo); + void hideMediaPreview(); void showLayer(LayeredWidget *box, ShowLayerOptions options = CloseOtherLayers); void hideLayer(bool fast = false); @@ -110,6 +111,7 @@ namespace Notify { void clipStopperHidden(ClipStopperType type); void historyItemLayoutChanged(const HistoryItem *item); + void inlineItemLayoutChanged(const InlineBots::Layout::ItemBase *layout); // handle pending resize() / paint() on history items void handlePendingHistoryUpdate(); diff --git a/Telegram/SourceFiles/history.cpp b/Telegram/SourceFiles/history.cpp index 56178baaf..e4e28b669 100644 --- a/Telegram/SourceFiles/history.cpp +++ b/Telegram/SourceFiles/history.cpp @@ -4452,7 +4452,7 @@ bool HistoryDocument::updateStatusText() const { audioPlayer()->currentState(&playing, &playingState, &playingPosition, &playingDuration, &playingFrequency); } - if (playing.msgId == _parent->fullId() && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) { + if (playing == AudioMsgId(_data, _parent->fullId()) && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) { if (auto voice = Get()) { bool was = voice->_playback; voice->ensurePlayback(this); @@ -4486,14 +4486,14 @@ bool HistoryDocument::updateStatusText() const { audioPlayer()->currentState(&playing, &playingState, &playingPosition, &playingDuration, &playingFrequency); } - if (playing.msgId == _parent->fullId() && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) { + if (playing == SongMsgId(_data, _parent->fullId()) && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) { statusSize = -1 - (playingPosition / (playingFrequency ? playingFrequency : AudioVoiceMsgFrequency)); realDuration = playingDuration / (playingFrequency ? playingFrequency : AudioVoiceMsgFrequency); showPause = (playingState == AudioPlayerPlaying || playingState == AudioPlayerResuming || playingState == AudioPlayerStarting); } else { statusSize = FileStatusSizeLoaded; } - if (!showPause && playing.msgId == _parent->fullId() && App::main() && App::main()->player()->seekingSong(playing)) { + if (!showPause && (playing == SongMsgId(_data, _parent->fullId())) && App::main() && App::main()->player()->seekingSong(playing)) { showPause = true; } } else { diff --git a/Telegram/SourceFiles/historywidget.cpp b/Telegram/SourceFiles/historywidget.cpp index 1750dafc4..5a1a6e729 100644 --- a/Telegram/SourceFiles/historywidget.cpp +++ b/Telegram/SourceFiles/historywidget.cpp @@ -6394,6 +6394,10 @@ void HistoryWidget::notify_historyItemLayoutChanged(const HistoryItem *item) { } } +void HistoryWidget::notify_inlineItemLayoutChanged(const InlineBots::Layout::ItemBase *layout) { + _emojiPan.notify_inlineItemLayoutChanged(layout); +} + void HistoryWidget::notify_handlePendingHistoryUpdate() { if (hasPendingResizedItems()) { updateListSize(); diff --git a/Telegram/SourceFiles/historywidget.h b/Telegram/SourceFiles/historywidget.h index beca58658..168ca5019 100644 --- a/Telegram/SourceFiles/historywidget.h +++ b/Telegram/SourceFiles/historywidget.h @@ -680,6 +680,7 @@ public: PeerData *ui_getPeerForMouseAction(); void notify_historyItemLayoutChanged(const HistoryItem *item); + void notify_inlineItemLayoutChanged(const InlineBots::Layout::ItemBase *layout); void notify_botCommandsChanged(UserData *user); void notify_inlineBotRequesting(bool requesting); void notify_replyMarkupUpdated(const HistoryItem *item); diff --git a/Telegram/SourceFiles/inline_bots/inline_bot_layout_internal.cpp b/Telegram/SourceFiles/inline_bots/inline_bot_layout_internal.cpp index 39c314b9a..8c7070a71 100644 --- a/Telegram/SourceFiles/inline_bots/inline_bot_layout_internal.cpp +++ b/Telegram/SourceFiles/inline_bots/inline_bot_layout_internal.cpp @@ -66,15 +66,25 @@ int FileBase::content_height() const { } int FileBase::content_duration() const { - DocumentData *document = getShownDocument(); - if (document->duration() > 0) { - return document->duration(); - } else if (SongData *song = document->song()) { - if (song->duration) { - return song->duration; + if (DocumentData *document = getShownDocument()) { + if (document->duration() > 0) { + return document->duration(); + } else if (SongData *song = document->song()) { + if (song->duration) { + return song->duration; + } } } - return 0; + return getResultDuration(); +} + +ImagePtr FileBase::content_thumb() const { + if (DocumentData *document = getShownDocument()) { + if (!document->thumb->isNull()) { + return document->thumb; + } + } + return getResultThumb(); } Gif::Gif(Result *result) : FileBase(result) { @@ -186,9 +196,6 @@ void Gif::paint(Painter &p, const QRect &clip, uint32 selection, const PaintCont p.drawSpriteLeft(deletePos, _width, st::stickerPanDelete); p.setOpacity(1); } - if (!document->hasRemoteLocation()) { - p.fillRect(10, 10, 30, 30, QColor(255, 0, 0)); - } } void Gif::getState(ClickHandlerPtr &link, HistoryCursorState &cursor, int x, int y) const { @@ -477,9 +484,6 @@ void Photo::paint(Painter &p, const QRect &clip, uint32 selection, const PaintCo } else { p.drawPixmap(r.topLeft(), _thumb); } - if (getShownPhoto()->full->toDelayedStorageImage()) { - p.fillRect(10, 10, 30, 30, QColor(255, 0, 0)); - } } void Photo::getState(ClickHandlerPtr &link, HistoryCursorState &cursor, int x, int y) const { @@ -560,7 +564,7 @@ Video::Video(Result *result) : FileBase(result) } void Video::initDimensions() { - bool withThumb = !getShownDocument()->thumb->isNull(); + bool withThumb = !content_thumb()->isNull(); _maxw = st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft; int32 textWidth = _maxw - (withThumb ? (st::inlineThumbSize + st::inlineThumbSkip) : 0); @@ -589,7 +593,7 @@ void Video::initDimensions() { void Video::paint(Painter &p, const QRect &clip, uint32 selection, const PaintContext *context) const { int left = st::inlineThumbSize + st::inlineThumbSkip; - bool withThumb = !getShownDocument()->thumb->isNull(); + bool withThumb = !content_thumb()->isNull(); if (withThumb) { prepareThumb(st::inlineThumbSize, st::inlineThumbSize); if (_thumb.isNull()) { @@ -636,7 +640,7 @@ void Video::getState(ClickHandlerPtr &link, HistoryCursorState &cursor, int x, i } void Video::prepareThumb(int32 width, int32 height) const { - ImagePtr thumb = getShownDocument()->thumb; + ImagePtr thumb = content_thumb(); if (thumb->loaded()) { if (_thumb.width() != width * cIntRetinaFactor() || _thumb.height() != height * cIntRetinaFactor()) { int32 w = qMax(convertScale(thumb->width()), 1), h = qMax(convertScale(thumb->height()), 1); @@ -668,9 +672,11 @@ void CancelFileClickHandler::onClickImpl() const { File::File(Result *result) : FileBase(result) , _title(st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft - st::msgFileSize - st::inlineThumbSkip) -, _description(st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft - st::msgFileSize - st::inlineThumbSkip) { -//, _open(new OpenFileClickHandler(result)) -//, _cancel(new CancelFileClickHandler(result)) { +, _description(st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft - st::msgFileSize - st::inlineThumbSkip) +, _open(new OpenFileClickHandler(result)) +, _cancel(new CancelFileClickHandler(result)) { + updateStatusText(); + regDocumentItem(getShownDocument(), this); } void File::initDimensions() { @@ -698,7 +704,7 @@ void File::paint(Painter &p, const QRect &clip, uint32 selection, const PaintCon _animation->radial.start(document->progress()); } } - bool showPause = false;// updateStatusText(parent); + bool showPause = updateStatusText(); bool radial = isRadialAnimation(context->ms); QRect iconCircle = rtlrect(0, st::inlineRowMargin, st::msgFileSize, st::msgFileSize, _width); @@ -715,28 +721,26 @@ void File::paint(Painter &p, const QRect &clip, uint32 selection, const PaintCon p.drawEllipse(iconCircle); p.setRenderHint(QPainter::HighQualityAntialiasing, false); + if (radial) { + QRect radialCircle(iconCircle.marginsRemoved(QMargins(st::msgFileRadialLine, st::msgFileRadialLine, st::msgFileRadialLine, st::msgFileRadialLine))); + _animation->radial.draw(p, radialCircle, st::msgFileRadialLine, st::msgInBg); + } + style::sprite icon; - //if (bool showPause = false) { - // icon = st::msgFileInPause; - //} else if (radial || content_loading()) { - // icon = st::msgFileInCancel; - //} else if (loaded) { - // //if (_data->song() || _data->voice()) { - // icon = st::msgFileInPlay; - // //} else if (_data->isImage()) { - // // icon = st::msgFileInImage; - // //} else { - // // icon = st::msgFileInFile; - // //} - //} else { - // icon = st::msgFileInDownload; - //} - if (document->isImage()) { - icon = st::msgFileInImage; - } else if (document->voice() || document->song()) { - icon = st::msgFileInPlay; + if (showPause) { + icon = st::msgFileInPause; + } else if (radial || document->loading()) { + icon = st::msgFileInCancel; + } else if (document->loaded()) { + if (document->isImage()) { + icon = st::msgFileInImage; + } else if (document->voice() || document->song()) { + icon = st::msgFileInPlay; + } else { + icon = st::msgFileInFile; + } } else { - icon = st::msgFileInFile; + icon = st::msgFileInDownload; } p.drawSpriteCenter(iconCircle, icon); @@ -747,7 +751,12 @@ void File::paint(Painter &p, const QRect &clip, uint32 selection, const PaintCon _title.drawLeftElided(p, left, titleTop, _width - left, _width); p.setPen(st::inlineDescriptionFg); - _description.drawLeftElided(p, left, descriptionTop, _width - left, _width); + if (_statusText.isEmpty()) { + _description.drawLeftElided(p, left, descriptionTop, _width - left, _width); + } else { + p.setFont(st::normalFont); + p.drawTextLeft(left, descriptionTop, _width, _statusText); + } if (!context->lastRow) { p.fillRect(rtlrect(left, _height - st::inlineRowBorder, _width - left, st::inlineRowBorder, _width), st::inlineRowBorderFg); @@ -767,17 +776,24 @@ void File::getState(ClickHandlerPtr &link, HistoryCursorState &cursor, int x, in void File::clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active) { if (p == _open || p == _cancel) { - if (active && !getShownDocument()->loaded()) { + if (active) { ensureAnimation(); _animation->a_thumbOver.start(1); - _animation->_a_thumbOver.start(); - } else if (!active && _animation) { + } else { + if (!_animation) { + ensureAnimation(); + _animation->a_thumbOver = anim::fvalue(1, 1); + } _animation->a_thumbOver.start(0); - _animation->_a_thumbOver.start(); } + _animation->_a_thumbOver.start(); } } +File::~File() { + unregDocumentItem(getShownDocument(), this); +} + void File::step_thumbOver(float64 ms, bool timer) { float64 dt = ms / st::msgFileOverDuration; if (dt >= 1) { @@ -797,7 +813,7 @@ void File::step_radial(uint64 ms, bool timer) { Ui::repaintInlineItem(this); } else { DocumentData *document = getShownDocument(); - _animation->radial.update(document->progress(), document->loaded(), ms); + _animation->radial.update(document->progress(), !document->loading() || document->loaded(), ms); if (!_animation->radial.animating()) { checkAnimationFinished(); } @@ -820,6 +836,83 @@ void File::checkAnimationFinished() { } } +bool File::updateStatusText() const { + bool showPause = false; + int32 statusSize = 0, realDuration = 0; + DocumentData *document = getShownDocument(); + if (document->status == FileDownloadFailed || document->status == FileUploadFailed) { + statusSize = FileStatusSizeFailed; + } else if (document->status == FileUploading) { + statusSize = document->uploadOffset; + } else if (document->loading()) { + statusSize = document->loadOffset(); + } else if (document->loaded()) { + if (document->voice()) { + AudioMsgId playing; + AudioPlayerState playingState = AudioPlayerStopped; + int64 playingPosition = 0, playingDuration = 0; + int32 playingFrequency = 0; + if (audioPlayer()) { + audioPlayer()->currentState(&playing, &playingState, &playingPosition, &playingDuration, &playingFrequency); + } + + if (playing == AudioMsgId(document, FullMsgId()) && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) { + statusSize = -1 - (playingPosition / (playingFrequency ? playingFrequency : AudioVoiceMsgFrequency)); + realDuration = playingDuration / (playingFrequency ? playingFrequency : AudioVoiceMsgFrequency); + showPause = (playingState == AudioPlayerPlaying || playingState == AudioPlayerResuming || playingState == AudioPlayerStarting); + } else { + statusSize = FileStatusSizeLoaded; + } + } else if (document->song()) { + SongMsgId playing; + AudioPlayerState playingState = AudioPlayerStopped; + int64 playingPosition = 0, playingDuration = 0; + int32 playingFrequency = 0; + if (audioPlayer()) { + audioPlayer()->currentState(&playing, &playingState, &playingPosition, &playingDuration, &playingFrequency); + } + + if (playing == SongMsgId(document, FullMsgId()) && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) { + statusSize = -1 - (playingPosition / (playingFrequency ? playingFrequency : AudioVoiceMsgFrequency)); + realDuration = playingDuration / (playingFrequency ? playingFrequency : AudioVoiceMsgFrequency); + showPause = (playingState == AudioPlayerPlaying || playingState == AudioPlayerResuming || playingState == AudioPlayerStarting); + } else { + statusSize = FileStatusSizeLoaded; + } + if (!showPause && (playing == SongMsgId(document, FullMsgId())) && App::main() && App::main()->player()->seekingSong(playing)) { + showPause = true; + } + } else { + statusSize = FileStatusSizeLoaded; + } + } else { + statusSize = FileStatusSizeReady; + } + if (statusSize != _statusSize) { + int32 duration = document->song() ? document->song()->duration : (document->voice() ? document->voice()->duration : -1); + setStatusSize(statusSize, document->size, duration, realDuration); + } + return showPause; +} + +void File::setStatusSize(int32 newSize, int32 fullSize, int32 duration, qint64 realDuration) const { + _statusSize = newSize; + if (_statusSize == FileStatusSizeReady) { +// _statusText = (duration >= 0) ? formatDurationAndSizeText(duration, fullSize) : (duration < -1 ? formatGifAndSizeText(fullSize) : formatSizeText(fullSize)); + _statusText = QString(); + } else if (_statusSize == FileStatusSizeLoaded) { +// _statusText = (duration >= 0) ? formatDurationText(duration) : (duration < -1 ? qsl("GIF") : formatSizeText(fullSize)); + _statusText = QString(); + } else if (_statusSize == FileStatusSizeFailed) { +// _statusText = lang(lng_attach_failed); + _statusText = QString(); + } else if (_statusSize >= 0) { + _statusText = formatDownloadText(_statusSize, fullSize); + } else { + _statusText = formatPlayedText(-_statusSize - 1, realDuration); + } +} + Contact::Contact(Result *result) : ItemBase(result) , _title(st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft - st::inlineThumbSize - st::inlineThumbSkip) , _description(st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft - st::inlineThumbSize - st::inlineThumbSkip) { diff --git a/Telegram/SourceFiles/inline_bots/inline_bot_layout_internal.h b/Telegram/SourceFiles/inline_bots/inline_bot_layout_internal.h index 93cd5e1fe..3acd16eb3 100644 --- a/Telegram/SourceFiles/inline_bots/inline_bot_layout_internal.h +++ b/Telegram/SourceFiles/inline_bots/inline_bot_layout_internal.h @@ -38,8 +38,8 @@ protected: int content_width() const; int content_height() const; - FileLocation content_location() const; int content_duration() const; + ImagePtr content_thumb() const; }; class DeleteSavedGifClickHandler : public LeftButtonClickHandler { @@ -244,16 +244,15 @@ public: // ClickHandlerHost interface void clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active) override; + ~File(); + private: - - Text _title, _description; - ClickHandlerPtr _open, _cancel; - void step_thumbOver(float64 ms, bool timer); void step_radial(uint64 ms, bool timer); void ensureAnimation() const; void checkAnimationFinished(); + bool updateStatusText() const; bool isRadialAnimation(uint64 ms) const { if (!_animation || !_animation->radial.animating()) return false; @@ -280,6 +279,19 @@ private: }; mutable UniquePointer _animation; + Text _title, _description; + ClickHandlerPtr _open, _cancel; + + // >= 0 will contain download / upload string, _statusSize = loaded bytes + // < 0 will contain played string, _statusSize = -(seconds + 1) played + // 0x7FFFFFF0 will contain status for not yet downloaded file + // 0x7FFFFFF1 will contain status for already downloaded file + // 0x7FFFFFF2 will contain status for failed to download / upload file + mutable int32 _statusSize; + mutable QString _statusText; + + // duration = -1 - no duration, duration = -2 - "GIF" duration + void setStatusSize(int32 newSize, int32 fullSize, int32 duration, qint64 realDuration) const; }; diff --git a/Telegram/SourceFiles/inline_bots/inline_bot_layout_item.cpp b/Telegram/SourceFiles/inline_bots/inline_bot_layout_item.cpp index b2c9e8c4e..f3fa345e9 100644 --- a/Telegram/SourceFiles/inline_bots/inline_bot_layout_item.cpp +++ b/Telegram/SourceFiles/inline_bots/inline_bot_layout_item.cpp @@ -67,6 +67,16 @@ DocumentData *ItemBase::getPreviewDocument() const { return nullptr; } +PhotoData *ItemBase::getPreviewPhoto() const { + if (_photo) { + return _photo; + } + if (_result) { + return _result->_photo; + } + return nullptr; +} + void ItemBase::preload() const { if (_result) { if (_result->_photo) { @@ -179,5 +189,35 @@ QString ItemBase::getResultThumbLetter() const { return QString(); } +namespace { + +NeverFreedPointer documentItemsMap; + +} // namespace + +const DocumentItems *documentItems() { + return documentItemsMap.data(); +} + +namespace internal { + +void regDocumentItem(DocumentData *document, ItemBase *item) { + documentItemsMap.makeIfNull(); + (*documentItemsMap)[document].insert(item); +} + +void unregDocumentItem(DocumentData *document, ItemBase *item) { + if (documentItemsMap) { + auto i = documentItemsMap->find(document); + if (i != documentItemsMap->cend()) { + if (i->remove(item) && i->isEmpty()) { + documentItemsMap->erase(i); + } + } + } +} + +} // namespace internal + } // namespace Layout } // namespace InlineBots diff --git a/Telegram/SourceFiles/inline_bots/inline_bot_layout_item.h b/Telegram/SourceFiles/inline_bots/inline_bot_layout_item.h index 7c3dc855b..76903873e 100644 --- a/Telegram/SourceFiles/inline_bots/inline_bot_layout_item.h +++ b/Telegram/SourceFiles/inline_bots/inline_bot_layout_item.h @@ -37,6 +37,7 @@ public: , lastRow(lastRow) { } bool paused, lastRow; + }; // this type used as a flag, we dynamic_cast<> to it @@ -73,9 +74,10 @@ public: DocumentData *getDocument() const; PhotoData *getPhoto() const; - // Get document (possibly from InlineBots::Result) for - // showing sticker or GIF preview. + // Get document or photo (possibly from InlineBots::Result) for + // showing sticker / GIF / photo preview by long mouse press. DocumentData *getPreviewDocument() const; + PhotoData *getPreviewPhoto() const; virtual void preload() const; @@ -113,5 +115,14 @@ protected: }; +using DocumentItems = QMap>; +const DocumentItems *documentItems(); + +namespace internal { + +void regDocumentItem(DocumentData *document, ItemBase *item); +void unregDocumentItem(DocumentData *document, ItemBase *item); + +} // namespace internal } // namespace Layout } // namespace InlineBots diff --git a/Telegram/SourceFiles/inline_bots/inline_bot_result.cpp b/Telegram/SourceFiles/inline_bots/inline_bot_result.cpp index 290a6158e..7f9bdf0f5 100644 --- a/Telegram/SourceFiles/inline_bots/inline_bot_result.cpp +++ b/Telegram/SourceFiles/inline_bots/inline_bot_result.cpp @@ -129,6 +129,19 @@ UniquePointer Result::create(uint64 queryId, const MTPBotInlineResult &m return UniquePointer(); } + // Ensure required media fields for layouts. + if (result->_type == Type::Photo) { + if (!result->_photo && result->_content_url.isEmpty()) { + return UniquePointer(); + } + result->createPhoto(); + } else if (result->_type == Type::File || result->_type == Type::Gif || result->_type == Type::Sticker) { + if (!result->_document && result->_content_url.isEmpty()) { + return UniquePointer(); + } + result->createDocument(); + } + switch (message->type()) { case mtpc_botInlineMessageMediaAuto: { const auto &r(message->c_botInlineMessageMediaAuto()); @@ -319,8 +332,9 @@ void Result::createPhoto() { QSize mediumsize = shrinkToKeepAspect(_width, _height, 320, 320); ImagePtr medium = ImagePtr(mediumsize.width(), mediumsize.height()); + ImagePtr full = ImagePtr(_content_url, _width, _height); uint64 photoId = rand_value(); - _photo = App::photoSet(photoId, 0, 0, unixtime(), _thumb, medium, ImagePtr(_width, _height)); + _photo = App::photoSet(photoId, 0, 0, unixtime(), _thumb, medium, full); _photo->thumb = _thumb; } diff --git a/Telegram/SourceFiles/layerwidget.cpp b/Telegram/SourceFiles/layerwidget.cpp index 6191b0705..6f843db98 100644 --- a/Telegram/SourceFiles/layerwidget.cpp +++ b/Telegram/SourceFiles/layerwidget.cpp @@ -190,17 +190,14 @@ BackgroundWidget::~BackgroundWidget() { } } -StickerPreviewWidget::StickerPreviewWidget(QWidget *parent) : TWidget(parent) +MediaPreviewWidget::MediaPreviewWidget(QWidget *parent) : TWidget(parent) , a_shown(0, 0) -, _a_shown(animation(this, &StickerPreviewWidget::step_shown)) -, _doc(0) -, _gif(0) -, _cacheStatus(CacheNotLoaded) { +, _a_shown(animation(this, &MediaPreviewWidget::step_shown)) { setAttribute(Qt::WA_TransparentForMouseEvents); connect(App::wnd(), SIGNAL(imageLoaded()), this, SLOT(update())); } -void StickerPreviewWidget::paintEvent(QPaintEvent *e) { +void MediaPreviewWidget::paintEvent(QPaintEvent *e) { Painter p(this); QRect r(e->rect()); @@ -216,11 +213,11 @@ void StickerPreviewWidget::paintEvent(QPaintEvent *e) { p.drawPixmap((width() - w) / 2, (height() - h) / 2, draw); } -void StickerPreviewWidget::resizeEvent(QResizeEvent *e) { +void MediaPreviewWidget::resizeEvent(QResizeEvent *e) { update(); } -void StickerPreviewWidget::step_shown(float64 ms, bool timer) { +void MediaPreviewWidget::step_shown(float64 ms, bool timer) { float64 dt = ms / st::stickerPreviewDuration; if (dt >= 1) { _a_shown.stop(); @@ -232,79 +229,126 @@ void StickerPreviewWidget::step_shown(float64 ms, bool timer) { if (timer) update(); } -void StickerPreviewWidget::showPreview(DocumentData *sticker) { - if (sticker && !sticker->isAnimation() && !sticker->sticker()) sticker = 0; - if (sticker) { - _cache = QPixmap(); - if (isHidden() || _a_shown.animating()) { - if (isHidden()) show(); - a_shown.start(1); - _a_shown.start(); - } else { - update(); - } - } else if (isHidden()) { +void MediaPreviewWidget::showPreview(DocumentData *document) { + if (!document || (!document->isAnimation() && !document->sticker())) { + hidePreview(); return; - } else { - if (_gif) _cache = currentImage(); - a_shown.start(0); - _a_shown.start(); } - _doc = sticker; + + startShow(); + _photo = nullptr; + _document = document; + resetGifAndCache(); +} + +void MediaPreviewWidget::showPreview(PhotoData *photo) { + if (!photo || photo->full->isNull()) { + hidePreview(); + return; + } + + startShow(); + _photo = photo; + _document = nullptr; + resetGifAndCache(); +} + +void MediaPreviewWidget::startShow() { + _cache = QPixmap(); + if (isHidden() || _a_shown.animating()) { + if (isHidden()) show(); + a_shown.start(1); + _a_shown.start(); + } else { + update(); + } +} + +void MediaPreviewWidget::hidePreview() { + if (isHidden()) { + return; + } + if (_gif) _cache = currentImage(); + a_shown.start(0); + _a_shown.start(); + _photo = nullptr; + _document = nullptr; + resetGifAndCache(); +} + +void MediaPreviewWidget::resetGifAndCache() { if (_gif) { if (gif()) { delete _gif; } - _gif = 0; + _gif = nullptr; } _cacheStatus = CacheNotLoaded; + _cachedSize = QSize(); } -void StickerPreviewWidget::hidePreview() { - showPreview(0); -} - -QSize StickerPreviewWidget::currentDimensions() const { - if (!_doc) return QSize(_cache.width() / cIntRetinaFactor(), _cache.height() / cIntRetinaFactor()); - - QSize result(qMax(convertScale(_doc->dimensions.width()), 1), qMax(convertScale(_doc->dimensions.height()), 1)); - if (gif() && _gif->ready()) { - result = QSize(qMax(convertScale(_gif->width()), 1), qMax(convertScale(_gif->height()), 1)); +QSize MediaPreviewWidget::currentDimensions() const { + if (!_cachedSize.isEmpty()) { + return _cachedSize; } - if (result.width() > st::maxStickerSize) { - result.setHeight(qMax(qRound((st::maxStickerSize * result.height()) / result.width()), 1)); - result.setWidth(st::maxStickerSize); + if (!_document && !_photo) { + _cachedSize = QSize(_cache.width() / cIntRetinaFactor(), _cache.height() / cIntRetinaFactor()); + return _cachedSize; } - if (result.height() > st::maxStickerSize) { - result.setWidth(qMax(qRound((st::maxStickerSize * result.width()) / result.height()), 1)); - result.setHeight(st::maxStickerSize); + + QSize result, box; + if (_photo) { + result = QSize(_photo->full->width(), _photo->full->height()); + box = QSize(width() - 2 * st::boxVerticalMargin, height() - 2 * st::boxVerticalMargin); + } else { + result = _document->dimensions; + if (gif() && _gif->ready()) { + result = QSize(_gif->width(), _gif->height()); + } + if (_document->sticker()) { + box = QSize(st::maxStickerSize, st::maxStickerSize); + } else { + box = QSize(2 * st::maxStickerSize, 2 * st::maxStickerSize); + } + } + result = QSize(qMax(convertScale(result.width()), 1), qMax(convertScale(result.height()), 1)); + if (result.width() > box.width()) { + result.setHeight(qMax((box.width() * result.height()) / result.width(), 1)); + result.setWidth(box.width()); + } + if (result.height() > box.height()) { + result.setWidth(qMax((box.height() * result.width()) / result.height(), 1)); + result.setHeight(box.height()); + } + if (_photo) { + _cachedSize = result; } return result; } -QPixmap StickerPreviewWidget::currentImage() const { - if (_doc) { - if (_doc->sticker()) { +QPixmap MediaPreviewWidget::currentImage() const { + if (_document) { + if (_document->sticker()) { if (_cacheStatus != CacheLoaded) { - _doc->checkSticker(); - if (_doc->sticker()->img->isNull()) { - if (_cacheStatus != CacheThumbLoaded && _doc->thumb->loaded()) { + _document->checkSticker(); + if (_document->sticker()->img->isNull()) { + if (_cacheStatus != CacheThumbLoaded && _document->thumb->loaded()) { QSize s = currentDimensions(); - _cache = _doc->thumb->pixBlurred(s.width(), s.height()); + _cache = _document->thumb->pixBlurred(s.width(), s.height()); _cacheStatus = CacheThumbLoaded; } } else { QSize s = currentDimensions(); - _cache = _doc->sticker()->img->pix(s.width(), s.height()); + _cache = _document->sticker()->img->pix(s.width(), s.height()); _cacheStatus = CacheLoaded; } } } else { - _doc->automaticLoad(0); - if (_doc->loaded()) { + _document->automaticLoad(nullptr); + if (_document->loaded()) { if (!_gif && _gif != BadClipReader) { - StickerPreviewWidget *that = const_cast(this); - that->_gif = new ClipReader(_doc->location(), _doc->data(), func(that, &StickerPreviewWidget::clipCallback)); + MediaPreviewWidget *that = const_cast(this); + that->_gif = new ClipReader(_document->location(), _document->data(), func(that, &MediaPreviewWidget::clipCallback)); if (gif()) _gif->setAutoplay(); } } @@ -312,17 +356,36 @@ QPixmap StickerPreviewWidget::currentImage() const { QSize s = currentDimensions(); return _gif->current(s.width(), s.height(), s.width(), s.height(), getms()); } - if (_cacheStatus != CacheThumbLoaded && _doc->thumb->loaded()) { + if (_cacheStatus != CacheThumbLoaded && _document->thumb->loaded()) { QSize s = currentDimensions(); - _cache = _doc->thumb->pixBlurred(s.width(), s.height()); + _cache = _document->thumb->pixBlurred(s.width(), s.height()); _cacheStatus = CacheThumbLoaded; } } + } else if (_photo) { + if (_cacheStatus != CacheLoaded) { + if (_photo->full->loaded()) { + QSize s = currentDimensions(); + LOG(("DIMENSIONS: %1 %2").arg(s.width()).arg(s.height())); + _cache = _photo->full->pix(s.width(), s.height()); + _cacheStatus = CacheLoaded; + } else { + if (_cacheStatus != CacheThumbLoaded && _photo->thumb->loaded()) { + QSize s = currentDimensions(); + LOG(("DIMENSIONS: %1 %2").arg(s.width()).arg(s.height())); + _cache = _photo->thumb->pixBlurred(s.width(), s.height()); + _cacheStatus = CacheThumbLoaded; + } + _photo->thumb->load(); + _photo->full->load(); + } + } + } return _cache; } -void StickerPreviewWidget::clipCallback(ClipReaderNotification notification) { +void MediaPreviewWidget::clipCallback(ClipReaderNotification notification) { switch (notification) { case ClipReaderReinit: { if (gif() && _gif->state() == ClipError) { @@ -346,5 +409,5 @@ void StickerPreviewWidget::clipCallback(ClipReaderNotification notification) { } } -StickerPreviewWidget::~StickerPreviewWidget() { +MediaPreviewWidget::~MediaPreviewWidget() { } diff --git a/Telegram/SourceFiles/layerwidget.h b/Telegram/SourceFiles/layerwidget.h index c7a143b1b..e1d408f1e 100644 --- a/Telegram/SourceFiles/layerwidget.h +++ b/Telegram/SourceFiles/layerwidget.h @@ -106,32 +106,36 @@ private: BoxShadow shadow; }; -class StickerPreviewWidget : public TWidget { +class MediaPreviewWidget : public TWidget { Q_OBJECT public: - StickerPreviewWidget(QWidget *parent); + MediaPreviewWidget(QWidget *parent); void paintEvent(QPaintEvent *e); void resizeEvent(QResizeEvent *e); void step_shown(float64 ms, bool timer); - void showPreview(DocumentData *sticker); + void showPreview(DocumentData *document); + void showPreview(PhotoData *photo); void hidePreview(); - ~StickerPreviewWidget(); + ~MediaPreviewWidget(); private: QSize currentDimensions() const; QPixmap currentImage() const; + void startShow(); + void resetGifAndCache(); anim::fvalue a_shown; Animation _a_shown; - DocumentData *_doc; - ClipReader *_gif; + DocumentData *_document = nullptr; + PhotoData *_photo = nullptr; + ClipReader *_gif = nullptr; bool gif() const { return (!_gif || _gif == BadClipReader) ? false : true; } @@ -143,7 +147,8 @@ private: CacheThumbLoaded, CacheLoaded, }; - mutable CacheStatus _cacheStatus; + mutable CacheStatus _cacheStatus = CacheNotLoaded; mutable QPixmap _cache; + mutable QSize _cachedSize; }; diff --git a/Telegram/SourceFiles/layout.cpp b/Telegram/SourceFiles/layout.cpp index 04eee040f..746dbe5f8 100644 --- a/Telegram/SourceFiles/layout.cpp +++ b/Telegram/SourceFiles/layout.cpp @@ -737,7 +737,7 @@ bool LayoutOverviewVoice::updateStatusText() const { audioPlayer()->currentState(&playing, &playingState, &playingPosition, &playingDuration, &playingFrequency); } - if (playing.msgId == _parent->fullId() && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) { + if (playing == AudioMsgId(_data, _parent->fullId()) && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) { statusSize = -1 - (playingPosition / (playingFrequency ? playingFrequency : AudioVoiceMsgFrequency)); realDuration = playingDuration / (playingFrequency ? playingFrequency : AudioVoiceMsgFrequency); showPause = (playingState == AudioPlayerPlaying || playingState == AudioPlayerResuming || playingState == AudioPlayerStarting); @@ -1046,14 +1046,14 @@ bool LayoutOverviewDocument::updateStatusText() const { audioPlayer()->currentState(&playing, &playingState, &playingPosition, &playingDuration, &playingFrequency); } - if (playing.msgId == _parent->fullId() && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) { + if (playing == SongMsgId(_data, _parent->fullId()) && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) { statusSize = -1 - (playingPosition / (playingFrequency ? playingFrequency : AudioVoiceMsgFrequency)); realDuration = playingDuration / (playingFrequency ? playingFrequency : AudioVoiceMsgFrequency); showPause = (playingState == AudioPlayerPlaying || playingState == AudioPlayerResuming || playingState == AudioPlayerStarting); } else { statusSize = FileStatusSizeLoaded; } - if (!showPause && playing.msgId == _parent->fullId() && App::main() && App::main()->player()->seekingSong(playing)) { + if (!showPause && (playing == SongMsgId(_data, _parent->fullId())) && App::main() && App::main()->player()->seekingSong(playing)) { showPause = true; } } else { diff --git a/Telegram/SourceFiles/layout.h b/Telegram/SourceFiles/layout.h index 5051b961a..9fbcf90c8 100644 --- a/Telegram/SourceFiles/layout.h +++ b/Telegram/SourceFiles/layout.h @@ -84,7 +84,6 @@ RoundCorners documentCorners(int32 colorIndex); class PaintContextBase { public: - PaintContextBase(uint64 ms, bool selecting) : ms(ms), selecting(selecting) { } uint64 ms; diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index 92fb38826..3d982e86b 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -19,15 +19,16 @@ Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org */ #include "stdafx.h" +#include "mainwidget.h" + #include "ui/style.h" #include "lang.h" - #include "boxes/addcontactbox.h" #include "fileuploader.h" #include "application.h" #include "window.h" #include "settingswidget.h" -#include "mainwidget.h" +#include "inline_bots/inline_bot_layout_item.h" #include "boxes/confirmbox.h" #include "boxes/stickersetbox.h" #include "boxes/contactsbox.h" @@ -838,6 +839,10 @@ void MainWidget::notify_historyItemLayoutChanged(const HistoryItem *item) { if (overview) overview->notify_historyItemLayoutChanged(item); } +void MainWidget::notify_inlineItemLayoutChanged(const InlineBots::Layout::ItemBase *layout) { + history.notify_inlineItemLayoutChanged(layout); +} + void MainWidget::notify_handlePendingHistoryUpdate() { history.notify_handlePendingHistoryUpdate(); } @@ -1854,9 +1859,14 @@ void MainWidget::audioPlayProgress(const AudioMsgId &audioId) { } } - if (HistoryItem *item = App::histItemById(audioId.msgId)) { + if (HistoryItem *item = App::histItemById(audioId.contextId)) { Ui::repaintHistoryItem(item); } + if (auto items = InlineBots::Layout::documentItems()) { + for (auto item : items->value(audioId.audio)) { + Ui::repaintInlineItem(item); + } + } } void MainWidget::documentPlayProgress(const SongMsgId &songId) { @@ -1889,9 +1899,14 @@ void MainWidget::documentPlayProgress(const SongMsgId &songId) { } } - if (HistoryItem *item = App::histItemById(songId.msgId)) { + if (HistoryItem *item = App::histItemById(songId.contextId)) { Ui::repaintHistoryItem(item); } + if (auto items = InlineBots::Layout::documentItems()) { + for (auto item : items->value(songId.song)) { + Ui::repaintInlineItem(item); + } + } } void MainWidget::hidePlayer() { diff --git a/Telegram/SourceFiles/mainwidget.h b/Telegram/SourceFiles/mainwidget.h index 557819b76..643612111 100644 --- a/Telegram/SourceFiles/mainwidget.h +++ b/Telegram/SourceFiles/mainwidget.h @@ -465,6 +465,7 @@ public: void notify_migrateUpdated(PeerData *peer); void notify_clipStopperHidden(ClipStopperType type); void notify_historyItemLayoutChanged(const HistoryItem *item); + void notify_inlineItemLayoutChanged(const InlineBots::Layout::ItemBase *layout); void notify_handlePendingHistoryUpdate(); void cmd_search(); diff --git a/Telegram/SourceFiles/mediaview.cpp b/Telegram/SourceFiles/mediaview.cpp index e0729d25c..9a1e974d3 100644 --- a/Telegram/SourceFiles/mediaview.cpp +++ b/Telegram/SourceFiles/mediaview.cpp @@ -862,7 +862,7 @@ void MediaView::showPhoto(PhotoData *photo, PeerData *context) { void MediaView::showDocument(DocumentData *doc, HistoryItem *context) { _photo = 0; - _history = context ? context->history() : 0; + _history = context ? context->history() : nullptr; if (_history) { if (_history->peer->migrateFrom()) { _migrated = App::history(_history->peer->migrateFrom()->id); @@ -910,7 +910,7 @@ void MediaView::displayPhoto(PhotoData *photo, HistoryItem *item) { _zoom = 0; _caption = Text(); - if (HistoryMessage *itemMsg = item ? item->toHistoryMessage() : 0) { + if (HistoryMessage *itemMsg = item ? item->toHistoryMessage() : nullptr) { if (HistoryPhoto *photoMsg = dynamic_cast(itemMsg->getMedia())) { _caption.setText(st::mvCaptionFont, photoMsg->getCaption(), (item->author()->isUser() && item->author()->asUser()->botInfo) ? _captionBotOptions : _captionTextOptions); } @@ -958,7 +958,7 @@ void MediaView::displayDocument(DocumentData *doc, HistoryItem *item) { // empty stopGif(); } _doc = doc; - _photo = 0; + _photo = nullptr; _current = QPixmap(); @@ -1087,7 +1087,11 @@ void MediaView::displayDocument(DocumentData *doc, HistoryItem *item) { // empty } _x = (width() - _w) / 2; _y = (height() - _h) / 2; - _from = item->authorOriginal(); + if (_msgid && item) { + _from = item->authorOriginal(); + } else { + _from = _user; + } _full = 1; updateControls(); if (isHidden()) { diff --git a/Telegram/SourceFiles/overviewwidget.cpp b/Telegram/SourceFiles/overviewwidget.cpp index 5732627a7..f9237984e 100644 --- a/Telegram/SourceFiles/overviewwidget.cpp +++ b/Telegram/SourceFiles/overviewwidget.cpp @@ -2107,7 +2107,7 @@ int32 OverviewWidget::countBestScroll() const { AudioPlayerState playingState = AudioPlayerStopped; audioPlayer()->currentState(&playing, &playingState); if (playing) { - int32 top = _inner.itemTop(playing.msgId); + int32 top = _inner.itemTop(playing.contextId); if (top >= 0) { return snap(top - int(_scroll.height() - (st::msgPadding.top() + st::mediaThumbSize + st::msgPadding.bottom())) / 2, 0, _scroll.scrollTopMax()); } diff --git a/Telegram/SourceFiles/playerwidget.cpp b/Telegram/SourceFiles/playerwidget.cpp index 7cb684c7f..7644265db 100644 --- a/Telegram/SourceFiles/playerwidget.cpp +++ b/Telegram/SourceFiles/playerwidget.cpp @@ -209,7 +209,7 @@ void PlayerWidget::mousePressEvent(QMouseEvent *e) { updateDownTime(); } } else if (_over == OverFull && _song) { - if (HistoryItem *item = App::histItemById(_song.msgId)) { + if (HistoryItem *item = App::histItemById(_song.contextId)) { App::main()->showMediaOverview(item->history()->peer, OverviewMusicFiles); } } else if (_over == OverRepeat) { @@ -294,12 +294,12 @@ void PlayerWidget::updateControls() { void PlayerWidget::findCurrent() { _index = -1; - if (!_history) return; + if (!_history || !_song.contextId.msg) return; const History::MediaOverview *o = &(_msgmigrated ? _migrated : _history)->overview[OverviewMusicFiles]; - if ((_msgmigrated ? _migrated : _history)->channelId() == _song.msgId.channel) { + if ((_msgmigrated ? _migrated : _history)->channelId() == _song.contextId.channel) { for (int i = 0, l = o->size(); i < l; ++i) { - if (o->at(i) == _song.msgId.msg) { + if (o->at(i) == _song.contextId.msg) { _index = i; break; } @@ -351,9 +351,9 @@ void PlayerWidget::mediaOverviewUpdated(PeerData *peer, MediaOverviewType type) if (_history && (_history->peer == peer || (_migrated && _migrated->peer == peer)) && type == OverviewMusicFiles) { _index = -1; History *history = _msgmigrated ? _migrated : _history; - if (history->channelId() == _song.msgId.channel) { + if (history->channelId() == _song.contextId.channel && _song.contextId.msg) { for (int i = 0, l = history->overview[OverviewMusicFiles].size(); i < l; ++i) { - if (history->overview[OverviewMusicFiles].at(i) == _song.msgId.msg) { + if (history->overview[OverviewMusicFiles].at(i) == _song.contextId.msg) { _index = i; preloadNext(); break; @@ -596,7 +596,7 @@ void PlayerWidget::updateState(SongMsgId playing, AudioPlayerState playingState, if (playing && _song != playing) { songChanged = true; _song = playing; - if (HistoryItem *item = App::histItemById(_song.msgId)) { + if (HistoryItem *item = App::histItemById(_song.contextId)) { _history = item->history(); if (_history->peer->migrateFrom()) { _migrated = App::history(_history->peer->migrateFrom()->id); @@ -608,7 +608,7 @@ void PlayerWidget::updateState(SongMsgId playing, AudioPlayerState playingState, } findCurrent(); } else { - _history = 0; + _history = nullptr; _msgmigrated = false; _index = -1; } @@ -691,13 +691,16 @@ void PlayerWidget::updateState(SongMsgId playing, AudioPlayerState playingState, if (wasPlaying && playingState == AudioPlayerStoppedAtEnd) { if (_repeat) { - startPlay(_song.msgId); + if (_song.song) { + audioPlayer()->play(_song); + updateState(); + } } else { nextPressed(); } } if (songChanged) { - emit playerSongChanged(_song.msgId); + emit playerSongChanged(_song.contextId); } } diff --git a/Telegram/SourceFiles/structs.cpp b/Telegram/SourceFiles/structs.cpp index facb95541..885d6dedd 100644 --- a/Telegram/SourceFiles/structs.cpp +++ b/Telegram/SourceFiles/structs.cpp @@ -19,9 +19,11 @@ Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org */ #include "stdafx.h" +#include "structs.h" + #include "ui/style.h" #include "lang.h" - +#include "inline_bots/inline_bot_layout_item.h" #include "history.h" #include "mainwidget.h" #include "application.h" @@ -853,10 +855,13 @@ QString documentSaveFilename(const DocumentData *data, bool forceSavingAs = fals void DocumentOpenClickHandler::doOpen(DocumentData *data, ActionOnLoad action) { if (!data->date) return; - HistoryItem *item = App::hoveredLinkItem() ? App::hoveredLinkItem() : (App::contextItem() ? App::contextItem() : 0); - - bool playVoice = data->voice() && audioPlayer() && item; - bool playMusic = data->song() && audioPlayer() && item; + HistoryItem *item = App::hoveredLinkItem() ? App::hoveredLinkItem() : (App::contextItem() ? App::contextItem() : nullptr); + FullMsgId msgId; + if (item) { + msgId = item->fullId(); + } + bool playVoice = data->voice() && audioPlayer(); + bool playMusic = data->song() && audioPlayer(); bool playAnimation = data->isAnimation() && item && item->getMedia(); const FileLocation &location(data->location(true)); if (!location.isEmpty() || (!data->data().isEmpty() && (playVoice || playMusic || playAnimation))) { @@ -864,10 +869,10 @@ void DocumentOpenClickHandler::doOpen(DocumentData *data, ActionOnLoad action) { AudioMsgId playing; AudioPlayerState playingState = AudioPlayerStopped; audioPlayer()->currentState(&playing, &playingState); - if (playing.msgId == item->fullId() && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) { + if (playing == AudioMsgId(data, msgId) && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) { audioPlayer()->pauseresume(OverviewVoiceFiles); } else { - AudioMsgId audio(data, item->fullId()); + AudioMsgId audio(data, msgId); audioPlayer()->play(audio); if (App::main()) { App::main()->audioPlayProgress(audio); @@ -878,10 +883,10 @@ void DocumentOpenClickHandler::doOpen(DocumentData *data, ActionOnLoad action) { SongMsgId playing; AudioPlayerState playingState = AudioPlayerStopped; audioPlayer()->currentState(&playing, &playingState); - if (playing.msgId == item->fullId() && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) { + if (playing == SongMsgId(data, msgId) && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) { audioPlayer()->pauseresume(OverviewFiles); } else { - SongMsgId song(data, item->fullId()); + SongMsgId song(data, msgId); audioPlayer()->play(song); if (App::main()) App::main()->documentPlayProgress(song); } @@ -896,8 +901,8 @@ void DocumentOpenClickHandler::doOpen(DocumentData *data, ActionOnLoad action) { App::wnd()->showDocument(data, item); } } else if (location.accessEnable()) { - if (item && (data->isAnimation() || QImageReader(location.name()).canRead())) { - if (action == ActionOnLoadPlayInline && item->getMedia()) { + if (data->isAnimation() || QImageReader(location.name()).canRead()) { + if (action == ActionOnLoadPlayInline && item && item->getMedia()) { item->getMedia()->playInline(item); } else { App::wnd()->showDocument(data, item); @@ -923,7 +928,7 @@ void DocumentOpenClickHandler::doOpen(DocumentData *data, ActionOnLoad action) { if (filename.isEmpty()) return; } - data->save(filename, action, item ? item->fullId() : FullMsgId()); + data->save(filename, action, msgId); } void DocumentOpenClickHandler::onClickImpl() const { @@ -1133,17 +1138,17 @@ void DocumentData::performActionOnLoad() { const FileLocation &loc(location(true)); QString already = loc.name(); - HistoryItem *item = _actionOnLoadMsgId.msg ? App::histItemById(_actionOnLoadMsgId) : 0; - bool showImage = !isVideo() && item && (size < MediaViewImageSizeLimit); - bool playVoice = voice() && audioPlayer() && (_actionOnLoad == ActionOnLoadPlayInline || _actionOnLoad == ActionOnLoadOpen) && item; - bool playMusic = song() && audioPlayer() && (_actionOnLoad == ActionOnLoadPlayInline || _actionOnLoad == ActionOnLoadOpen) && item; - bool playAnimation = isAnimation() && (_actionOnLoad == ActionOnLoadPlayInline || _actionOnLoad == ActionOnLoadOpen) && showImage && item->getMedia(); + HistoryItem *item = _actionOnLoadMsgId.msg ? App::histItemById(_actionOnLoadMsgId) : nullptr; + bool showImage = !isVideo() && (size < MediaViewImageSizeLimit); + bool playVoice = voice() && audioPlayer() && (_actionOnLoad == ActionOnLoadPlayInline || _actionOnLoad == ActionOnLoadOpen); + bool playMusic = song() && audioPlayer() && (_actionOnLoad == ActionOnLoadPlayInline || _actionOnLoad == ActionOnLoadOpen); + bool playAnimation = isAnimation() && (_actionOnLoad == ActionOnLoadPlayInline || _actionOnLoad == ActionOnLoadOpen) && showImage && item && item->getMedia(); if (playVoice) { if (loaded()) { AudioMsgId playing; AudioPlayerState state = AudioPlayerStopped; audioPlayer()->currentState(&playing, &state); - if (playing.msgId == _actionOnLoadMsgId && !(state & AudioPlayerStoppedMask) && state != AudioPlayerFinishing) { + if (playing == AudioMsgId(this, _actionOnLoadMsgId) && !(state & AudioPlayerStoppedMask) && state != AudioPlayerFinishing) { audioPlayer()->pauseresume(OverviewVoiceFiles); } else { audioPlayer()->play(AudioMsgId(this, _actionOnLoadMsgId)); @@ -1155,10 +1160,10 @@ void DocumentData::performActionOnLoad() { SongMsgId playing; AudioPlayerState playingState = AudioPlayerStopped; audioPlayer()->currentState(&playing, &playingState); - if (playing.msgId == item->fullId() && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) { + if (playing == SongMsgId(this, _actionOnLoadMsgId) && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) { audioPlayer()->pauseresume(OverviewFiles); } else { - SongMsgId song(this, item->fullId()); + SongMsgId song(this, _actionOnLoadMsgId); audioPlayer()->play(song); if (App::main()) App::main()->documentPlayProgress(song); } @@ -1185,7 +1190,7 @@ void DocumentData::performActionOnLoad() { if (App::main()) App::main()->mediaMarkRead(this); } else if (loc.accessEnable()) { if (showImage && QImageReader(loc.name()).canRead()) { - if (_actionOnLoad == ActionOnLoadPlayInline && item->getMedia()) { + if (_actionOnLoad == ActionOnLoadPlayInline && item && item->getMedia()) { item->getMedia()->playInline(item); } else { App::wnd()->showDocument(this, item); @@ -1322,6 +1327,12 @@ void DocumentData::notifyLayoutChanged() const { Notify::historyItemLayoutChanged(j.key()); } } + + if (auto items = InlineBots::Layout::documentItems()) { + for (auto item : items->value(const_cast(this))) { + Notify::inlineItemLayoutChanged(item); + } + } } VoiceWaveform documentWaveformDecode(const QByteArray &encoded5bit) { diff --git a/Telegram/SourceFiles/structs.h b/Telegram/SourceFiles/structs.h index 48542432e..8074564e8 100644 --- a/Telegram/SourceFiles/structs.h +++ b/Telegram/SourceFiles/structs.h @@ -1157,49 +1157,50 @@ VoiceWaveform documentWaveformDecode(const QByteArray &encoded5bit); QByteArray documentWaveformEncode5bit(const VoiceWaveform &waveform); struct SongMsgId { - SongMsgId() : song(0) { + SongMsgId() : song(nullptr) { } - SongMsgId(DocumentData *song, const FullMsgId &msgId) : song(song), msgId(msgId) { + SongMsgId(DocumentData *song, const FullMsgId &msgId) : song(song), contextId(msgId) { } - SongMsgId(DocumentData *song, ChannelId channelId, MsgId msgId) : song(song), msgId(channelId, msgId) { + SongMsgId(DocumentData *song, ChannelId channelId, MsgId msgId) : song(song), contextId(channelId, msgId) { } - operator bool() const { + explicit operator bool() const { return song; } DocumentData *song; - FullMsgId msgId; + FullMsgId contextId; }; inline bool operator<(const SongMsgId &a, const SongMsgId &b) { - return quintptr(a.song) < quintptr(b.song) || (quintptr(a.song) == quintptr(b.song) && a.msgId < b.msgId); + return quintptr(a.song) < quintptr(b.song) || (quintptr(a.song) == quintptr(b.song) && a.contextId < b.contextId); } inline bool operator==(const SongMsgId &a, const SongMsgId &b) { - return a.song == b.song && a.msgId == b.msgId; + return a.song == b.song && a.contextId == b.contextId; } inline bool operator!=(const SongMsgId &a, const SongMsgId &b) { return !(a == b); } struct AudioMsgId { - AudioMsgId() : audio(0) { + AudioMsgId() : audio(nullptr) { } - AudioMsgId(DocumentData *audio, const FullMsgId &msgId) : audio(audio), msgId(msgId) { + AudioMsgId(DocumentData *audio, const FullMsgId &msgId) : audio(audio), contextId(msgId) { } - AudioMsgId(DocumentData *audio, ChannelId channelId, MsgId msgId) : audio(audio), msgId(channelId, msgId) { + AudioMsgId(DocumentData *audio, ChannelId channelId, MsgId msgId) : audio(audio), contextId(channelId, msgId) { } - operator bool() const { + + explicit operator bool() const { return audio; } DocumentData *audio; - FullMsgId msgId; + FullMsgId contextId; }; inline bool operator<(const AudioMsgId &a, const AudioMsgId &b) { - return quintptr(a.audio) < quintptr(b.audio) || (quintptr(a.audio) == quintptr(b.audio) && a.msgId < b.msgId); + return quintptr(a.audio) < quintptr(b.audio) || (quintptr(a.audio) == quintptr(b.audio) && a.contextId < b.contextId); } inline bool operator==(const AudioMsgId &a, const AudioMsgId &b) { - return a.audio == b.audio && a.msgId == b.msgId; + return a.audio == b.audio && a.contextId == b.contextId; } inline bool operator!=(const AudioMsgId &a, const AudioMsgId &b) { return !(a == b); diff --git a/Telegram/SourceFiles/ui/images.cpp b/Telegram/SourceFiles/ui/images.cpp index 4466951cb..32500cd0d 100644 --- a/Telegram/SourceFiles/ui/images.cpp +++ b/Telegram/SourceFiles/ui/images.cpp @@ -30,7 +30,7 @@ namespace { typedef QMap LocalImages; LocalImages localImages; - typedef QMap WebImages; + typedef QMap WebImages; WebImages webImages; Image *blank() { @@ -944,6 +944,14 @@ void DelayedStorageImage::cancel() { WebImage::WebImage(const QString &url, QSize box) : _url(url), _box(box), _size(0), _width(0), _height(0) { } +WebImage::WebImage(const QString &url, int width, int height) : _url(url), _size(0), _width(width), _height(height) { +} + +void WebImage::setSize(int width, int height) { + _width = width; + _height = height; +} + int32 WebImage::countWidth() const { return _width; } @@ -954,8 +962,7 @@ int32 WebImage::countHeight() const { void WebImage::setInformation(int32 size, int32 width, int32 height) { _size = size; - _width = width; - _height = height; + setSize(width, height); } FileLoader *WebImage::createLoader(LoadFromCloudSetting fromCloud, bool autoLoading) { @@ -992,6 +999,17 @@ Image *getImage(const QString &url, QSize box) { return i.value(); } +Image *getImage(const QString &url, int width, int height) { + QString key = url; + auto i = webImages.constFind(key); + if (i == webImages.cend()) { + i = webImages.insert(key, new WebImage(url, width, height)); + } else { + i.value()->setSize(width, height); + } + return i.value(); +} + Image *getImage(const QByteArray &filecontent, QByteArray format) { return new Image(filecontent, format); } diff --git a/Telegram/SourceFiles/ui/images.h b/Telegram/SourceFiles/ui/images.h index 02eafc8e7..036c48f33 100644 --- a/Telegram/SourceFiles/ui/images.h +++ b/Telegram/SourceFiles/ui/images.h @@ -353,6 +353,9 @@ public: // If !box.isEmpty() then resize the image to fit in this box. WebImage(const QString &url, QSize box = QSize()); + WebImage(const QString &url, int width, int height); + + void setSize(int width, int height); protected: @@ -375,6 +378,7 @@ private: namespace internal { Image *getImage(const QString &file, QByteArray format); Image *getImage(const QString &url, QSize box); + Image *getImage(const QString &url, int width, int height); Image *getImage(const QByteArray &filecontent, QByteArray format); Image *getImage(const QPixmap &pixmap, QByteArray format); Image *getImage(const QByteArray &filecontent, QByteArray format, const QPixmap &pixmap); @@ -390,6 +394,8 @@ public: } ImagePtr(const QString &url, QSize box) : Parent(internal::getImage(url, box)) { } + ImagePtr(const QString &url, int width, int height) : Parent(internal::getImage(url, width, height)) { + } ImagePtr(const QByteArray &filecontent, QByteArray format = QByteArray()) : Parent(internal::getImage(filecontent, format)) { } ImagePtr(const QByteArray &filecontent, QByteArray format, const QPixmap &pixmap) : Parent(internal::getImage(filecontent, format, pixmap)) { diff --git a/Telegram/SourceFiles/window.cpp b/Telegram/SourceFiles/window.cpp index 21771276e..68b8a18d7 100644 --- a/Telegram/SourceFiles/window.cpp +++ b/Telegram/SourceFiles/window.cpp @@ -364,23 +364,7 @@ NotifyWindow::~NotifyWindow() { if (App::wnd()) App::wnd()->notifyShowNext(this); } -Window::Window(QWidget *parent) : PsMainWindow(parent) -, _serviceHistoryRequest(0) -, title(0) -, _passcode(0) -, intro(0) -, main(0) -, settings(0) -, layerBg(0) -, _stickerPreview(0) -, _isActive(false) -, _connecting(0) -, _clearManager(0) -, dragging(false) -, _inactivePress(false) -, _shouldLockAt(0) -, _mediaView(0) { - +Window::Window(QWidget *parent) : PsMainWindow(parent) { icon16 = icon256.scaledToWidth(16, Qt::SmoothTransformation); icon32 = icon256.scaledToWidth(32, Qt::SmoothTransformation); icon64 = icon256.scaledToWidth(64, Qt::SmoothTransformation); @@ -861,21 +845,33 @@ bool Window::ui_isMediaViewShown() { return _mediaView && !_mediaView->isHidden(); } -void Window::ui_showStickerPreview(DocumentData *sticker) { - if (!sticker || ((!sticker->isAnimation() || !sticker->loaded()) && !sticker->sticker())) return; - if (!_stickerPreview) { - _stickerPreview = new StickerPreviewWidget(this); - resizeEvent(0); +void Window::ui_showMediaPreview(DocumentData *document) { + if (!document || ((!document->isAnimation() || !document->loaded()) && !document->sticker())) return; + if (!_mediaPreview) { + _mediaPreview = MakeUnique(this); + resizeEvent(nullptr); } - if (_stickerPreview->isHidden()) { + if (_mediaPreview->isHidden()) { fixOrder(); } - _stickerPreview->showPreview(sticker); + _mediaPreview->showPreview(document); } -void Window::ui_hideStickerPreview() { - if (!_stickerPreview) return; - _stickerPreview->hidePreview(); +void Window::ui_showMediaPreview(PhotoData *photo) { + if (!photo) return; + if (!_mediaPreview) { + _mediaPreview = MakeUnique(this); + resizeEvent(nullptr); + } + if (_mediaPreview->isHidden()) { + fixOrder(); + } + _mediaPreview->showPreview(photo); +} + +void Window::ui_hideMediaPreview() { + if (!_mediaPreview) return; + _mediaPreview->hidePreview(); } PeerData *Window::ui_getPeerForMouseAction() { @@ -1040,7 +1036,7 @@ bool Window::eventFilter(QObject *obj, QEvent *e) { break; case QEvent::MouseButtonRelease: - Ui::hideStickerPreview(); + Ui::hideMediaPreview(); break; case QEvent::ShortcutOverride: // handle shortcuts ourselves @@ -1249,7 +1245,7 @@ void Window::layerFinishedHide(BackgroundWidget *was) { void Window::fixOrder() { title->raise(); if (layerBg) layerBg->raise(); - if (_stickerPreview) _stickerPreview->raise(); + if (_mediaPreview) _mediaPreview->raise(); if (_connecting) _connecting->raise(); } @@ -1321,7 +1317,7 @@ void Window::resizeEvent(QResizeEvent *e) { } title->setGeometry(0, 0, width(), st::titleHeight); if (layerBg) layerBg->resize(width(), height()); - if (_stickerPreview) _stickerPreview->setGeometry(0, title->height(), width(), height() - title->height()); + if (_mediaPreview) _mediaPreview->setGeometry(0, title->height(), width(), height() - title->height()); if (_connecting) _connecting->setGeometry(0, height() - _connecting->height(), _connecting->width(), _connecting->height()); emit resized(QSize(width(), height() - st::titleHeight)); } @@ -1921,7 +1917,6 @@ void Window::updateIsActive(int timeout) { Window::~Window() { notifyClearFast(); - deleteAndMark(_stickerPreview); delete _clearManager; delete _connecting; delete _mediaView; diff --git a/Telegram/SourceFiles/window.h b/Telegram/SourceFiles/window.h index 13f7513ee..a0c0ed911 100644 --- a/Telegram/SourceFiles/window.h +++ b/Telegram/SourceFiles/window.h @@ -121,7 +121,7 @@ private: typedef QList NotifyWindows; -class StickerPreviewWidget; +class MediaPreviewWidget; class Window : public PsMainWindow { Q_OBJECT @@ -239,8 +239,9 @@ public: void ui_showLayer(LayeredWidget *box, ShowLayerOptions options); bool ui_isLayerShown(); bool ui_isMediaViewShown(); - void ui_showStickerPreview(DocumentData *sticker); - void ui_hideStickerPreview(); + void ui_showMediaPreview(DocumentData *document); + void ui_showMediaPreview(PhotoData *photo); + void ui_hideMediaPreview(); PeerData *ui_getPeerForMouseAction(); public slots: @@ -306,33 +307,33 @@ private: typedef QPair DelayedServiceMsg; QVector _delayedServiceMsgs; - mtpRequestId _serviceHistoryRequest; + mtpRequestId _serviceHistoryRequest = 0; - TitleWidget *title; - PasscodeWidget *_passcode; - IntroWidget *intro; - MainWidget *main; - SettingsWidget *settings; - BackgroundWidget *layerBg; - StickerPreviewWidget *_stickerPreview; + TitleWidget *title = nullptr; + PasscodeWidget *_passcode = nullptr; + IntroWidget *intro = nullptr; + MainWidget *main = nullptr; + SettingsWidget *settings = nullptr; + BackgroundWidget *layerBg = nullptr; + UniquePointer _mediaPreview; QTimer _isActiveTimer; - bool _isActive; + bool _isActive = false; - ConnectingWidget *_connecting; + ConnectingWidget *_connecting = nullptr; - Local::ClearManager *_clearManager; + Local::ClearManager *_clearManager = nullptr; void clearWidgets(); - bool dragging; + bool dragging = false; QPoint dragStart; - bool _inactivePress; + bool _inactivePress = false; QTimer _inactiveTimer; SingleTimer _autoLockTimer; - uint64 _shouldLockAt; + uint64 _shouldLockAt = 0; typedef QMap NotifyWhenMap; typedef QMap NotifyWhenMaps; @@ -355,7 +356,7 @@ private: NotifyWindows notifyWindows; - MediaView *_mediaView; + MediaView *_mediaView = nullptr; }; class PreLaunchWindow : public TWidget { diff --git a/Telegram/Telegram.rc b/Telegram/Telegram.rc index 246a516cc..c63b15f69 100644 --- a/Telegram/Telegram.rc +++ b/Telegram/Telegram.rc @@ -34,8 +34,8 @@ IDI_ICON1 ICON "Resources\\art\\icon256.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,9,40,124 - PRODUCTVERSION 0,9,40,124 + FILEVERSION 0,9,40,126 + PRODUCTVERSION 0,9,40,126 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -51,10 +51,10 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "CompanyName", "Telegram Messenger LLP" - VALUE "FileVersion", "0.9.40.124" + VALUE "FileVersion", "0.9.40.126" VALUE "LegalCopyright", "Copyright (C) 2014-2016" VALUE "ProductName", "Telegram Desktop" - VALUE "ProductVersion", "0.9.40.124" + VALUE "ProductVersion", "0.9.40.126" END END BLOCK "VarFileInfo" diff --git a/Telegram/Version b/Telegram/Version index 226fa757e..c5c1a32e8 100644 --- a/Telegram/Version +++ b/Telegram/Version @@ -3,4 +3,4 @@ AppVersionStrMajor 0.9 AppVersionStrSmall 0.9.40 AppVersionStr 0.9.40 DevChannel 0 -BetaVersion 9040124 +BetaVersion 9040126