mirror of https://github.com/procxx/kepka.git
Encapsulated inline bot result class. Started inline bot
result downloading by external links, not ready (at all).
This commit is contained in:
parent
1e72c8a89b
commit
3be34a4bb7
|
@ -832,6 +832,49 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// This pointer is used for static non-POD variables that are allocated
|
||||||
|
// on first use by constructor and are never automatically freed.
|
||||||
|
template <typename T>
|
||||||
|
class StaticNeverFreedPointer {
|
||||||
|
public:
|
||||||
|
explicit StaticNeverFreedPointer(T *p) : _p(p) {
|
||||||
|
}
|
||||||
|
StaticNeverFreedPointer(const StaticNeverFreedPointer<T> &other) = delete;
|
||||||
|
StaticNeverFreedPointer &operator=(const StaticNeverFreedPointer<T> &other) = delete;
|
||||||
|
|
||||||
|
T *data() const {
|
||||||
|
return _p;
|
||||||
|
}
|
||||||
|
T *release() {
|
||||||
|
return getPointerAndReset(_p);
|
||||||
|
}
|
||||||
|
void reset(T *p = nullptr) {
|
||||||
|
delete _p;
|
||||||
|
_p = p;
|
||||||
|
}
|
||||||
|
bool isNull() const {
|
||||||
|
return data() == nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear() {
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
T *operator->() const {
|
||||||
|
return data();
|
||||||
|
}
|
||||||
|
T &operator*() const {
|
||||||
|
t_assert(!isNull());
|
||||||
|
return *data();
|
||||||
|
}
|
||||||
|
explicit operator bool() const {
|
||||||
|
return !isNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
T *_p = nullptr;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
template <typename I>
|
template <typename I>
|
||||||
inline void destroyImplementation(I *&ptr) {
|
inline void destroyImplementation(I *&ptr) {
|
||||||
if (ptr) {
|
if (ptr) {
|
||||||
|
|
|
@ -1458,82 +1458,25 @@ void StickerPanInner::mouseReleaseEvent(QMouseEvent *e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
InlineItem *item = _inlineRows.at(row).items.at(col);
|
InlineItem *item = _inlineRows.at(row).items.at(col);
|
||||||
PhotoData *photo = item->getPhoto();
|
if (PhotoData *photo = item->getPhoto()) {
|
||||||
DocumentData *document = item->getDocument();
|
if (photo->medium->loaded() || photo->thumb->loaded()) {
|
||||||
InlineResult *inlineResult = item->getResult();
|
|
||||||
using Type = InlineResult::Type;
|
|
||||||
auto getShownPhoto = [photo, inlineResult]() -> PhotoData* {
|
|
||||||
if (photo) {
|
|
||||||
return photo;
|
|
||||||
} else if (inlineResult && inlineResult->type == Type::Photo) {
|
|
||||||
return inlineResult->photo;
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
};
|
|
||||||
auto getShownDocument = [document, inlineResult]() -> DocumentData* {
|
|
||||||
auto inlineResultIsFileType = [](InlineResult *inlineResult) {
|
|
||||||
return inlineResult->type == Type::Video ||
|
|
||||||
inlineResult->type == Type::Audio ||
|
|
||||||
inlineResult->type == Type::Sticker ||
|
|
||||||
inlineResult->type == Type::File ||
|
|
||||||
inlineResult->type == Type::Gif;
|
|
||||||
};
|
|
||||||
if (document) {
|
|
||||||
return document;
|
|
||||||
} else if (inlineResult && inlineResultIsFileType(inlineResult)) {
|
|
||||||
return inlineResult->document;
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
};
|
|
||||||
auto sendInlineItem = [photo, document, inlineResult, this]() -> void {
|
|
||||||
if (photo) {
|
|
||||||
emit selected(photo);
|
emit selected(photo);
|
||||||
} else if (document) {
|
} else if (!photo->medium->loading()) {
|
||||||
|
photo->thumb->loadEvenCancelled();
|
||||||
|
photo->medium->loadEvenCancelled();
|
||||||
|
}
|
||||||
|
} else if (DocumentData *document = item->getDocument()) {
|
||||||
|
if (document->loaded()) {
|
||||||
emit selected(document);
|
emit selected(document);
|
||||||
} else if (inlineResult) {
|
} else if (document->loading()) {
|
||||||
|
document->cancel();
|
||||||
|
} else {
|
||||||
|
DocumentOpenClickHandler::doOpen(document, ActionOnLoadNone);
|
||||||
|
}
|
||||||
|
} else if (InlineResult *inlineResult = item->getResult()) {
|
||||||
|
if (inlineResult->onChoose(item)) {
|
||||||
emit selected(inlineResult, _inlineBot);
|
emit selected(inlineResult, _inlineBot);
|
||||||
}
|
}
|
||||||
};
|
|
||||||
if (PhotoData *shownPhoto = getShownPhoto()) {
|
|
||||||
if (shownPhoto->medium->loaded() || shownPhoto->thumb->loaded()) {
|
|
||||||
sendInlineItem();
|
|
||||||
} else if (!shownPhoto->medium->loading()) {
|
|
||||||
shownPhoto->thumb->loadEvenCancelled();
|
|
||||||
shownPhoto->medium->loadEvenCancelled();
|
|
||||||
}
|
|
||||||
} else if (DocumentData *shownDocument = getShownDocument()) {
|
|
||||||
if (!inlineResult || inlineResult->type == Type::Gif) {
|
|
||||||
if (shownDocument->loaded()) {
|
|
||||||
sendInlineItem();
|
|
||||||
} else if (shownDocument->loading()) {
|
|
||||||
shownDocument->cancel();
|
|
||||||
} else {
|
|
||||||
DocumentOpenClickHandler::doOpen(shownDocument, ActionOnLoadNone);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
sendInlineItem();
|
|
||||||
}
|
|
||||||
} else if (inlineResult) {
|
|
||||||
if (inlineResult->type == Type::Photo) {
|
|
||||||
if (inlineResult->thumb->loaded()) {
|
|
||||||
sendInlineItem();
|
|
||||||
} else if (!inlineResult->thumb->loading()) {
|
|
||||||
inlineResult->thumb->loadEvenCancelled();
|
|
||||||
Ui::repaintInlineItem(item);
|
|
||||||
}
|
|
||||||
} else if (inlineResult->type == Type::Gif) {
|
|
||||||
if (inlineResult->loaded()) {
|
|
||||||
sendInlineItem();
|
|
||||||
} else if (inlineResult->loading()) {
|
|
||||||
inlineResult->cancelFile();
|
|
||||||
Ui::repaintInlineItem(item);
|
|
||||||
} else {
|
|
||||||
inlineResult->saveFile(QString(), LoadFromCloudOrLocal, false);
|
|
||||||
Ui::repaintInlineItem(item);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
sendInlineItem();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1655,12 +1598,7 @@ void StickerPanInner::hideFinish(bool completely) {
|
||||||
photo->forget();
|
photo->forget();
|
||||||
}
|
}
|
||||||
if (InlineResult *result = item->getResult()) {
|
if (InlineResult *result = item->getResult()) {
|
||||||
if (DocumentData *document = result->document) {
|
result->forget();
|
||||||
document->forget();
|
|
||||||
}
|
|
||||||
if (PhotoData *photo = result->photo) {
|
|
||||||
photo->forget();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
clearInlineRows(false);
|
clearInlineRows(false);
|
||||||
|
|
|
@ -6775,7 +6775,7 @@ void HistoryWidget::onInlineResultSend(InlineBots::Result *result, UserData *bot
|
||||||
|
|
||||||
result->addToHistory(_history, flags, messageId, messageFromId, messageDate, messageViaBotId, replyToId());
|
result->addToHistory(_history, flags, messageId, messageFromId, messageDate, messageViaBotId, replyToId());
|
||||||
|
|
||||||
_history->sendRequestId = MTP::send(MTPmessages_SendInlineBotResult(MTP_flags(sendFlags), _peer->input, MTP_int(replyToId()), MTP_long(randomId), MTP_long(result->queryId), MTP_string(result->id)), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcFail(&MainWidget::sendMessageFail), 0, 0, _history->sendRequestId);
|
_history->sendRequestId = MTP::send(MTPmessages_SendInlineBotResult(MTP_flags(sendFlags), _peer->input, MTP_int(replyToId()), MTP_long(randomId), MTP_long(result->getQueryId()), MTP_string(result->getId())), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcFail(&MainWidget::sendMessageFail), 0, 0, _history->sendRequestId);
|
||||||
App::main()->finishForwarding(_history, _broadcast.checked(), _silent.checked());
|
App::main()->finishForwarding(_history, _broadcast.checked(), _silent.checked());
|
||||||
cancelReply(lastKeyboardUsed);
|
cancelReply(lastKeyboardUsed);
|
||||||
|
|
||||||
|
|
|
@ -38,10 +38,8 @@ FileBase::FileBase(DocumentData *document) : ItemBase(document) {
|
||||||
DocumentData *FileBase::getShownDocument() const {
|
DocumentData *FileBase::getShownDocument() const {
|
||||||
if (DocumentData *result = getDocument()) {
|
if (DocumentData *result = getDocument()) {
|
||||||
return result;
|
return result;
|
||||||
} else if (Result *result = getResult()) {
|
|
||||||
return result->document;
|
|
||||||
}
|
}
|
||||||
return nullptr;
|
return getResultDocument();
|
||||||
}
|
}
|
||||||
|
|
||||||
int FileBase::content_width() const {
|
int FileBase::content_width() const {
|
||||||
|
@ -52,10 +50,8 @@ int FileBase::content_width() const {
|
||||||
if (!document->thumb->isNull()) {
|
if (!document->thumb->isNull()) {
|
||||||
return convertScale(document->thumb->width());
|
return convertScale(document->thumb->width());
|
||||||
}
|
}
|
||||||
} else if (_result) {
|
|
||||||
return _result->width;
|
|
||||||
}
|
}
|
||||||
return 0;
|
return getResultWidth();
|
||||||
}
|
}
|
||||||
|
|
||||||
int FileBase::content_height() const {
|
int FileBase::content_height() const {
|
||||||
|
@ -66,10 +62,8 @@ int FileBase::content_height() const {
|
||||||
if (!document->thumb->isNull()) {
|
if (!document->thumb->isNull()) {
|
||||||
return convertScale(document->thumb->height());
|
return convertScale(document->thumb->height());
|
||||||
}
|
}
|
||||||
} else if (_result) {
|
|
||||||
return _result->height;
|
|
||||||
}
|
}
|
||||||
return 0;
|
return getResultHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FileBase::content_loading() const {
|
bool FileBase::content_loading() const {
|
||||||
|
@ -136,23 +130,20 @@ ImagePtr FileBase::content_thumb() const {
|
||||||
return document->thumb;
|
return document->thumb;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (_result->photo && !_result->photo->thumb->isNull()) {
|
return getResultThumb();
|
||||||
return _result->photo->thumb;
|
|
||||||
}
|
|
||||||
return _result->thumb;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int FileBase::content_duration() const {
|
int FileBase::content_duration() const {
|
||||||
if (_result->document) {
|
if (DocumentData *document = getShownDocument()) {
|
||||||
if (_result->document->duration() > 0) {
|
if (document->duration() > 0) {
|
||||||
return _result->document->duration();
|
return document->duration();
|
||||||
} else if (SongData *song = _result->document->song()) {
|
} else if (SongData *song = document->song()) {
|
||||||
if (song->duration) {
|
if (song->duration) {
|
||||||
return song->duration;
|
return song->duration;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return _result->duration;
|
return getResultDuration();
|
||||||
}
|
}
|
||||||
|
|
||||||
Gif::Gif(Result *result) : FileBase(result) {
|
Gif::Gif(Result *result) : FileBase(result) {
|
||||||
|
@ -354,13 +345,14 @@ void Gif::prepareThumb(int32 width, int32 height, const QSize &frame) const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!_result->thumb_url.isEmpty()) {
|
ImagePtr thumb = getResultThumb();
|
||||||
if (_result->thumb->loaded()) {
|
if (!thumb->isNull()) {
|
||||||
|
if (thumb->loaded()) {
|
||||||
if (_thumb.width() != width * cIntRetinaFactor() || _thumb.height() != height * cIntRetinaFactor()) {
|
if (_thumb.width() != width * cIntRetinaFactor() || _thumb.height() != height * cIntRetinaFactor()) {
|
||||||
_thumb = _result->thumb->pixNoCache(frame.width() * cIntRetinaFactor(), frame.height() * cIntRetinaFactor(), ImagePixSmooth, width, height);
|
_thumb = thumb->pixNoCache(frame.width() * cIntRetinaFactor(), frame.height() * cIntRetinaFactor(), ImagePixSmooth, width, height);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_result->thumb->load();
|
thumb->load();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -437,8 +429,11 @@ void Sticker::preload() const {
|
||||||
} else {
|
} else {
|
||||||
document->checkSticker();
|
document->checkSticker();
|
||||||
}
|
}
|
||||||
} else if (!_result->thumb->isNull()) {
|
} else {
|
||||||
_result->thumb->load();
|
ImagePtr thumb = getResultThumb();
|
||||||
|
if (!thumb->isNull()) {
|
||||||
|
thumb->load();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -506,14 +501,15 @@ void Sticker::prepareThumb() const {
|
||||||
_thumbLoaded = true;
|
_thumbLoaded = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (_result->thumb->loaded()) {
|
ImagePtr thumb = getResultThumb();
|
||||||
|
if (thumb->loaded()) {
|
||||||
if (!_thumbLoaded) {
|
if (!_thumbLoaded) {
|
||||||
QSize thumbSize = getThumbSize();
|
QSize thumbSize = getThumbSize();
|
||||||
_thumb = _result->thumb->pix(thumbSize.width(), thumbSize.height());
|
_thumb = thumb->pix(thumbSize.width(), thumbSize.height());
|
||||||
_thumbLoaded = true;
|
_thumbLoaded = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_result->thumb->load();
|
thumb->load();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -557,10 +553,8 @@ void Photo::getState(ClickHandlerPtr &link, HistoryCursorState &cursor, int32 x,
|
||||||
PhotoData *Photo::getShownPhoto() const {
|
PhotoData *Photo::getShownPhoto() const {
|
||||||
if (PhotoData *result = getPhoto()) {
|
if (PhotoData *result = getPhoto()) {
|
||||||
return result;
|
return result;
|
||||||
} else if (Result *result = getResult()) {
|
|
||||||
return result->photo;
|
|
||||||
}
|
}
|
||||||
return nullptr;
|
return getResultPhoto();
|
||||||
}
|
}
|
||||||
|
|
||||||
QSize Photo::countFrameSize() const {
|
QSize Photo::countFrameSize() const {
|
||||||
|
@ -605,12 +599,13 @@ void Photo::prepareThumb(int32 width, int32 height, const QSize &frame) const {
|
||||||
photo->medium->load();
|
photo->medium->load();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (_result->thumb->loaded()) {
|
ImagePtr thumb = getResultThumb();
|
||||||
|
if (thumb->loaded()) {
|
||||||
if (_thumb.width() != width * cIntRetinaFactor() || _thumb.height() != height * cIntRetinaFactor()) {
|
if (_thumb.width() != width * cIntRetinaFactor() || _thumb.height() != height * cIntRetinaFactor()) {
|
||||||
_thumb = _result->thumb->pixNoCache(frame.width() * cIntRetinaFactor(), frame.height() * cIntRetinaFactor(), ImagePixSmooth, width, height);
|
_thumb = thumb->pixNoCache(frame.width() * cIntRetinaFactor(), frame.height() * cIntRetinaFactor(), ImagePixSmooth, width, height);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_result->thumb->load();
|
thumb->load();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -618,19 +613,15 @@ void Photo::prepareThumb(int32 width, int32 height, const QSize &frame) const {
|
||||||
int Photo::content_width() const {
|
int Photo::content_width() const {
|
||||||
if (PhotoData *photo = getShownPhoto()) {
|
if (PhotoData *photo = getShownPhoto()) {
|
||||||
return photo->full->width();
|
return photo->full->width();
|
||||||
} else if (_result) {
|
|
||||||
return _result->width;
|
|
||||||
}
|
}
|
||||||
return 0;
|
return getResultWidth();
|
||||||
}
|
}
|
||||||
|
|
||||||
int Photo::content_height() const {
|
int Photo::content_height() const {
|
||||||
if (PhotoData *photo = getShownPhoto()) {
|
if (PhotoData *photo = getShownPhoto()) {
|
||||||
return photo->full->height();
|
return photo->full->height();
|
||||||
} else if (_result) {
|
|
||||||
return _result->height;
|
|
||||||
}
|
}
|
||||||
return 0;
|
return getResultHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Photo::content_loaded() const {
|
bool Photo::content_loaded() const {
|
||||||
|
@ -649,11 +640,9 @@ void Photo::content_forget() {
|
||||||
}
|
}
|
||||||
|
|
||||||
Video::Video(Result *result) : FileBase(result)
|
Video::Video(Result *result) : FileBase(result)
|
||||||
|
, _link(getResultContentUrlHandler())
|
||||||
, _title(st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft - st::inlineThumbSize - st::inlineThumbSkip)
|
, _title(st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft - st::inlineThumbSize - st::inlineThumbSkip)
|
||||||
, _description(st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft - st::inlineThumbSize - st::inlineThumbSkip) {
|
, _description(st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft - st::inlineThumbSize - st::inlineThumbSkip) {
|
||||||
if (!result->content_url.isEmpty()) {
|
|
||||||
_link = clickHandlerFromUrl(result->content_url);
|
|
||||||
}
|
|
||||||
if (int duration = content_duration()) {
|
if (int duration = content_duration()) {
|
||||||
_duration = formatDurationText(duration);
|
_duration = formatDurationText(duration);
|
||||||
}
|
}
|
||||||
|
@ -749,7 +738,7 @@ void Video::prepareThumb(int32 width, int32 height) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenFileClickHandler::onClickImpl() const {
|
void OpenFileClickHandler::onClickImpl() const {
|
||||||
_result->automaticLoadGif();
|
_result->openFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CancelFileClickHandler::onClickImpl() const {
|
void CancelFileClickHandler::onClickImpl() const {
|
||||||
|
@ -907,52 +896,23 @@ void File::checkAnimationFinished() {
|
||||||
}
|
}
|
||||||
|
|
||||||
Article::Article(Result *result, bool withThumb) : ItemBase(result)
|
Article::Article(Result *result, bool withThumb) : ItemBase(result)
|
||||||
|
, _url(getResultUrlHandler())
|
||||||
|
, _link(getResultContentUrlHandler())
|
||||||
, _withThumb(withThumb)
|
, _withThumb(withThumb)
|
||||||
, _title(st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft - st::inlineThumbSize - st::inlineThumbSkip)
|
, _title(st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft - st::inlineThumbSize - st::inlineThumbSkip)
|
||||||
, _description(st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft - st::inlineThumbSize - st::inlineThumbSkip) {
|
, _description(st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft - st::inlineThumbSize - st::inlineThumbSkip) {
|
||||||
if (!result->url.isEmpty()) {
|
|
||||||
_url = clickHandlerFromUrl(result->url);
|
|
||||||
}
|
|
||||||
if (!result->content_url.isEmpty()) {
|
|
||||||
_link = clickHandlerFromUrl(result->content_url);
|
|
||||||
} else {
|
|
||||||
LocationCoords location;
|
LocationCoords location;
|
||||||
if (result->getLocationCoords(&location)) {
|
if (!_link && result->getLocationCoords(&location)) {
|
||||||
_link.reset(new LocationClickHandler(location));
|
_link.reset(new LocationClickHandler(location));
|
||||||
int32 w = st::inlineThumbSize, h = st::inlineThumbSize;
|
|
||||||
int32 zoom = 13, scale = 1;
|
|
||||||
if (cScale() == dbisTwo || cRetina()) {
|
|
||||||
scale = 2;
|
|
||||||
w /= 2;
|
|
||||||
h /= 2;
|
|
||||||
}
|
|
||||||
QString coords = qsl("%1,%2").arg(location.lat).arg(location.lon);
|
|
||||||
QString url = qsl("https://maps.googleapis.com/maps/api/staticmap?center=") + coords + qsl("&zoom=%1&size=%2x%3&maptype=roadmap&scale=%4&markers=color:red|size:big|").arg(zoom).arg(w).arg(h).arg(scale) + coords + qsl("&sensor=false");
|
|
||||||
result->thumb = ImagePtr(url);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
QVector<QStringRef> parts = _result->url.splitRef('/');
|
|
||||||
if (!parts.isEmpty()) {
|
|
||||||
QStringRef domain = parts.at(0);
|
|
||||||
if (parts.size() > 2 && domain.endsWith(':') && parts.at(1).isEmpty()) { // http:// and others
|
|
||||||
domain = parts.at(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
parts = domain.split('@').back().split('.');
|
|
||||||
if (parts.size() > 1) {
|
|
||||||
_letter = parts.at(parts.size() - 2).at(0).toUpper();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (_letter.isEmpty() && !_result->title.isEmpty()) {
|
|
||||||
_letter = _result->title.at(0).toUpper();
|
|
||||||
}
|
}
|
||||||
|
_thumbLetter = getResultThumbLetter();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Article::initDimensions() {
|
void Article::initDimensions() {
|
||||||
_maxw = st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft;
|
_maxw = st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft;
|
||||||
int32 textWidth = _maxw - (_withThumb ? (st::inlineThumbSize + st::inlineThumbSkip) : 0);
|
int32 textWidth = _maxw - (_withThumb ? (st::inlineThumbSize + st::inlineThumbSkip) : 0);
|
||||||
TextParseOptions titleOpts = { 0, _maxw, 2 * st::semiboldFont->height, Qt::LayoutDirectionAuto };
|
TextParseOptions titleOpts = { 0, _maxw, 2 * st::semiboldFont->height, Qt::LayoutDirectionAuto };
|
||||||
_title.setText(st::semiboldFont, textOneLine(_result->title), titleOpts);
|
_title.setText(st::semiboldFont, textOneLine(_result->getLayoutTitle()), titleOpts);
|
||||||
int32 titleHeight = qMin(_title.countHeight(_maxw), 2 * st::semiboldFont->height);
|
int32 titleHeight = qMin(_title.countHeight(_maxw), 2 * st::semiboldFont->height);
|
||||||
|
|
||||||
int32 descriptionLines = (_withThumb || _url) ? 2 : 3;
|
int32 descriptionLines = (_withThumb || _url) ? 2 : 3;
|
||||||
|
@ -970,10 +930,10 @@ void Article::initDimensions() {
|
||||||
int32 Article::resizeGetHeight(int32 width) {
|
int32 Article::resizeGetHeight(int32 width) {
|
||||||
_width = qMin(width, _maxw);
|
_width = qMin(width, _maxw);
|
||||||
if (_url) {
|
if (_url) {
|
||||||
_urlText = _result->url;
|
_urlText = getResultUrl();
|
||||||
_urlWidth = st::normalFont->width(_urlText);
|
_urlWidth = st::normalFont->width(_urlText);
|
||||||
if (_urlWidth > _width - st::inlineThumbSize - st::inlineThumbSkip) {
|
if (_urlWidth > _width - st::inlineThumbSize - st::inlineThumbSkip) {
|
||||||
_urlText = st::normalFont->elided(_result->url, _width - st::inlineThumbSize - st::inlineThumbSkip);
|
_urlText = st::normalFont->elided(_urlText, _width - st::inlineThumbSize - st::inlineThumbSkip);
|
||||||
_urlWidth = st::normalFont->width(_urlText);
|
_urlWidth = st::normalFont->width(_urlText);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -988,15 +948,16 @@ void Article::paint(Painter &p, const QRect &clip, uint32 selection, const Paint
|
||||||
prepareThumb(st::inlineThumbSize, st::inlineThumbSize);
|
prepareThumb(st::inlineThumbSize, st::inlineThumbSize);
|
||||||
QRect rthumb(rtlrect(0, st::inlineRowMargin, st::inlineThumbSize, st::inlineThumbSize, _width));
|
QRect rthumb(rtlrect(0, st::inlineRowMargin, st::inlineThumbSize, st::inlineThumbSize, _width));
|
||||||
if (_thumb.isNull()) {
|
if (_thumb.isNull()) {
|
||||||
if (_result->thumb->isNull() && !_letter.isEmpty()) {
|
ImagePtr thumb = getResultThumb();
|
||||||
int32 index = (_letter.at(0).unicode() % 4);
|
if (thumb->isNull() && !_thumbLetter.isEmpty()) {
|
||||||
|
int32 index = (_thumbLetter.at(0).unicode() % 4);
|
||||||
style::color colors[] = { st::msgFileRedColor, st::msgFileYellowColor, st::msgFileGreenColor, st::msgFileBlueColor };
|
style::color colors[] = { st::msgFileRedColor, st::msgFileYellowColor, st::msgFileGreenColor, st::msgFileBlueColor };
|
||||||
|
|
||||||
p.fillRect(rthumb, colors[index]);
|
p.fillRect(rthumb, colors[index]);
|
||||||
if (!_letter.isEmpty()) {
|
if (!_thumbLetter.isEmpty()) {
|
||||||
p.setFont(st::linksLetterFont);
|
p.setFont(st::linksLetterFont);
|
||||||
p.setPen(st::white);
|
p.setPen(st::white);
|
||||||
p.drawText(rthumb, _letter, style::al_center);
|
p.drawText(rthumb, _thumbLetter, style::al_center);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
p.fillRect(rthumb, st::overviewPhotoBg);
|
p.fillRect(rthumb, st::overviewPhotoBg);
|
||||||
|
@ -1047,18 +1008,17 @@ void Article::getState(ClickHandlerPtr &link, HistoryCursorState &cursor, int32
|
||||||
}
|
}
|
||||||
|
|
||||||
void Article::prepareThumb(int32 width, int32 height) const {
|
void Article::prepareThumb(int32 width, int32 height) const {
|
||||||
if (_result->thumb->isNull()) {
|
ImagePtr thumb = getResultThumb();
|
||||||
if (_result->type == Result::Type::Contact) {
|
if (thumb->isNull()) {
|
||||||
if (_thumb.width() != width * cIntRetinaFactor() || _thumb.height() != height * cIntRetinaFactor()) {
|
if (_thumb.width() != width * cIntRetinaFactor() || _thumb.height() != height * cIntRetinaFactor()) {
|
||||||
_thumb = userDefPhoto(qHash(_result->id) % UserColorsCount)->pixCircled(width, height);
|
_thumb = getResultContactAvatar(width, height);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_result->thumb->loaded()) {
|
if (thumb->loaded()) {
|
||||||
if (_thumb.width() != width * cIntRetinaFactor() || _thumb.height() != height * cIntRetinaFactor()) {
|
if (_thumb.width() != width * cIntRetinaFactor() || _thumb.height() != height * cIntRetinaFactor()) {
|
||||||
int32 w = qMax(convertScale(_result->thumb->width()), 1), h = qMax(convertScale(_result->thumb->height()), 1);
|
int32 w = qMax(convertScale(thumb->width()), 1), h = qMax(convertScale(thumb->height()), 1);
|
||||||
if (w * height > h * width) {
|
if (w * height > h * width) {
|
||||||
if (height < h) {
|
if (height < h) {
|
||||||
w = w * height / h;
|
w = w * height / h;
|
||||||
|
@ -1070,10 +1030,10 @@ void Article::prepareThumb(int32 width, int32 height) const {
|
||||||
w = width;
|
w = width;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_thumb = _result->thumb->pixNoCache(w * cIntRetinaFactor(), h * cIntRetinaFactor(), ImagePixSmooth, width, height);
|
_thumb = thumb->pixNoCache(w * cIntRetinaFactor(), h * cIntRetinaFactor(), ImagePixSmooth, width, height);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_result->thumb->load();
|
thumb->load();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -313,7 +313,7 @@ private:
|
||||||
bool _withThumb;
|
bool _withThumb;
|
||||||
mutable QPixmap _thumb;
|
mutable QPixmap _thumb;
|
||||||
Text _title, _description;
|
Text _title, _description;
|
||||||
QString _letter, _urlText;
|
QString _thumbLetter, _urlText;
|
||||||
int32 _urlWidth;
|
int32 _urlWidth;
|
||||||
|
|
||||||
void prepareThumb(int32 width, int32 height) const;
|
void prepareThumb(int32 width, int32 height) const;
|
||||||
|
|
|
@ -51,12 +51,12 @@ PhotoData *ItemBase::getPhoto() const {
|
||||||
|
|
||||||
void ItemBase::preload() const {
|
void ItemBase::preload() const {
|
||||||
if (_result) {
|
if (_result) {
|
||||||
if (_result->photo) {
|
if (_result->_photo) {
|
||||||
_result->photo->thumb->load();
|
_result->_photo->thumb->load();
|
||||||
} else if (_result->document) {
|
} else if (_result->_document) {
|
||||||
_result->document->thumb->load();
|
_result->_document->thumb->load();
|
||||||
} else if (!_result->thumb->isNull()) {
|
} else if (!_result->_thumb->isNull()) {
|
||||||
_result->thumb->load();
|
_result->_thumb->load();
|
||||||
}
|
}
|
||||||
} else if (_doc) {
|
} else if (_doc) {
|
||||||
_doc->thumb->load();
|
_doc->thumb->load();
|
||||||
|
@ -74,7 +74,7 @@ void ItemBase::update() {
|
||||||
UniquePointer<ItemBase> ItemBase::createLayout(Result *result, bool forceThumb) {
|
UniquePointer<ItemBase> ItemBase::createLayout(Result *result, bool forceThumb) {
|
||||||
using Type = Result::Type;
|
using Type = Result::Type;
|
||||||
|
|
||||||
switch (result->type) {
|
switch (result->_type) {
|
||||||
case Type::Photo: return MakeUnique<internal::Photo>(result); break;
|
case Type::Photo: return MakeUnique<internal::Photo>(result); break;
|
||||||
case Type::Audio:
|
case Type::Audio:
|
||||||
case Type::File: return MakeUnique<internal::File>(result); break;
|
case Type::File: return MakeUnique<internal::File>(result); break;
|
||||||
|
@ -92,5 +92,82 @@ UniquePointer<ItemBase> ItemBase::createLayoutGif(DocumentData *document) {
|
||||||
return MakeUnique<internal::Gif>(document, true);
|
return MakeUnique<internal::Gif>(document, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DocumentData *ItemBase::getResultDocument() const {
|
||||||
|
return _result ? _result->_document : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
PhotoData *ItemBase::getResultPhoto() const {
|
||||||
|
return _result ? _result->_photo : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ItemBase::getResultWidth() const {
|
||||||
|
return _result ? _result->_width : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ItemBase::getResultHeight() const {
|
||||||
|
return _result ? _result->_height : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImagePtr ItemBase::getResultThumb() const {
|
||||||
|
if (_result) {
|
||||||
|
if (_result->_photo && !_result->_photo->thumb->isNull()) {
|
||||||
|
return _result->_photo->thumb;
|
||||||
|
}
|
||||||
|
if (!_result->_thumb->isNull()) {
|
||||||
|
return _result->_thumb;
|
||||||
|
}
|
||||||
|
return _result->_locationThumb;
|
||||||
|
}
|
||||||
|
return ImagePtr();
|
||||||
|
}
|
||||||
|
|
||||||
|
QPixmap ItemBase::getResultContactAvatar(int width, int height) const {
|
||||||
|
if (_result->_type == Result::Type::Contact) {
|
||||||
|
return userDefPhoto(qHash(_result->_id) % UserColorsCount)->pixCircled(width, height);
|
||||||
|
}
|
||||||
|
return QPixmap();
|
||||||
|
}
|
||||||
|
|
||||||
|
int ItemBase::getResultDuration() const {
|
||||||
|
return _result->_duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString ItemBase::getResultUrl() const {
|
||||||
|
return _result->_url;
|
||||||
|
}
|
||||||
|
|
||||||
|
ClickHandlerPtr ItemBase::getResultUrlHandler() const {
|
||||||
|
if (!_result->_url.isEmpty()) {
|
||||||
|
return clickHandlerFromUrl(_result->_url);
|
||||||
|
}
|
||||||
|
return ClickHandlerPtr();
|
||||||
|
}
|
||||||
|
|
||||||
|
ClickHandlerPtr ItemBase::getResultContentUrlHandler() const {
|
||||||
|
if (!_result->_content_url.isEmpty()) {
|
||||||
|
return clickHandlerFromUrl(_result->_content_url);
|
||||||
|
}
|
||||||
|
return ClickHandlerPtr();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString ItemBase::getResultThumbLetter() const {
|
||||||
|
QVector<QStringRef> parts = _result->_url.splitRef('/');
|
||||||
|
if (!parts.isEmpty()) {
|
||||||
|
QStringRef domain = parts.at(0);
|
||||||
|
if (parts.size() > 2 && domain.endsWith(':') && parts.at(1).isEmpty()) { // http:// and others
|
||||||
|
domain = parts.at(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
parts = domain.split('@').back().split('.');
|
||||||
|
if (parts.size() > 1) {
|
||||||
|
return parts.at(parts.size() - 2).at(0).toUpper();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!_result->_title.isEmpty()) {
|
||||||
|
return _result->_title.at(0).toUpper();
|
||||||
|
}
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Layout
|
} // namespace Layout
|
||||||
} // namespace InlineBots
|
} // namespace InlineBots
|
||||||
|
|
|
@ -89,6 +89,18 @@ public:
|
||||||
static UniquePointer<ItemBase> createLayoutGif(DocumentData *document);
|
static UniquePointer<ItemBase> createLayoutGif(DocumentData *document);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
DocumentData *getResultDocument() const;
|
||||||
|
PhotoData *getResultPhoto() const;
|
||||||
|
int getResultWidth() const;
|
||||||
|
int getResultHeight() const;
|
||||||
|
ImagePtr getResultThumb() const;
|
||||||
|
QPixmap getResultContactAvatar(int width, int height) const;
|
||||||
|
int getResultDuration() const;
|
||||||
|
QString getResultUrl() const;
|
||||||
|
ClickHandlerPtr getResultUrlHandler() const;
|
||||||
|
ClickHandlerPtr getResultContentUrlHandler() const;
|
||||||
|
QString getResultThumbLetter() const;
|
||||||
|
|
||||||
Result *_result = nullptr;
|
Result *_result = nullptr;
|
||||||
DocumentData *_doc = nullptr;
|
DocumentData *_doc = nullptr;
|
||||||
PhotoData *_photo = nullptr;
|
PhotoData *_photo = nullptr;
|
||||||
|
|
|
@ -56,18 +56,12 @@ Result *getResultFromLoader(FileLoader *loader) {
|
||||||
return ResultsByLoader->value(loader, nullptr);
|
return ResultsByLoader->value(loader, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
Result::Result(const Creator &creator) : _queryId(creator.queryId), _type(creator.type) {
|
||||||
|
|
||||||
using StringToTypeMap = QMap<QString, Result::Type>;
|
|
||||||
NeverFreedPointer<StringToTypeMap> stringToTypeMap;
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
Result::Result(const Creator &creator) : queryId(creator.queryId), type(creator.type) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UniquePointer<Result> Result::create(uint64 queryId, const MTPBotInlineResult &mtpData) {
|
UniquePointer<Result> Result::create(uint64 queryId, const MTPBotInlineResult &mtpData) {
|
||||||
stringToTypeMap.createIfNull([]() -> StringToTypeMap* {
|
using StringToTypeMap = QMap<QString, Result::Type>;
|
||||||
|
StaticNeverFreedPointer<StringToTypeMap> stringToTypeMap{ ([]() -> StringToTypeMap* {
|
||||||
auto result = MakeUnique<StringToTypeMap>();
|
auto result = MakeUnique<StringToTypeMap>();
|
||||||
result->insert(qsl("photo"), Result::Type::Photo);
|
result->insert(qsl("photo"), Result::Type::Photo);
|
||||||
result->insert(qsl("video"), Result::Type::Video);
|
result->insert(qsl("video"), Result::Type::Video);
|
||||||
|
@ -79,8 +73,9 @@ UniquePointer<Result> Result::create(uint64 queryId, const MTPBotInlineResult &m
|
||||||
result->insert(qsl("contact"), Result::Type::Contact);
|
result->insert(qsl("contact"), Result::Type::Contact);
|
||||||
result->insert(qsl("venue"), Result::Type::Venue);
|
result->insert(qsl("venue"), Result::Type::Venue);
|
||||||
return result.release();
|
return result.release();
|
||||||
});
|
})() };
|
||||||
auto getInlineResultType = [](const MTPBotInlineResult &inlineResult) -> Type {
|
|
||||||
|
auto getInlineResultType = [&stringToTypeMap](const MTPBotInlineResult &inlineResult) -> Type {
|
||||||
QString type;
|
QString type;
|
||||||
switch (inlineResult.type()) {
|
switch (inlineResult.type()) {
|
||||||
case mtpc_botInlineResult: type = qs(inlineResult.c_botInlineResult().vtype); break;
|
case mtpc_botInlineResult: type = qs(inlineResult.c_botInlineResult().vtype); break;
|
||||||
|
@ -98,32 +93,38 @@ UniquePointer<Result> Result::create(uint64 queryId, const MTPBotInlineResult &m
|
||||||
switch (mtpData.type()) {
|
switch (mtpData.type()) {
|
||||||
case mtpc_botInlineResult: {
|
case mtpc_botInlineResult: {
|
||||||
const MTPDbotInlineResult &r(mtpData.c_botInlineResult());
|
const MTPDbotInlineResult &r(mtpData.c_botInlineResult());
|
||||||
result->id = qs(r.vid);
|
result->_id = qs(r.vid);
|
||||||
if (r.has_title()) result->title = qs(r.vtitle);
|
if (r.has_title()) result->_title = qs(r.vtitle);
|
||||||
if (r.has_description()) result->description = qs(r.vdescription);
|
if (r.has_description()) result->_description = qs(r.vdescription);
|
||||||
if (r.has_url()) result->url = qs(r.vurl);
|
if (r.has_url()) result->_url = qs(r.vurl);
|
||||||
if (r.has_thumb_url()) result->thumb_url = qs(r.vthumb_url);
|
if (r.has_thumb_url()) result->_thumb_url = qs(r.vthumb_url);
|
||||||
if (r.has_content_type()) result->content_type = qs(r.vcontent_type);
|
if (r.has_content_type()) result->_content_type = qs(r.vcontent_type);
|
||||||
if (r.has_content_url()) result->content_url = qs(r.vcontent_url);
|
if (r.has_content_url()) result->_content_url = qs(r.vcontent_url);
|
||||||
if (r.has_w()) result->width = r.vw.v;
|
if (r.has_w()) result->_width = r.vw.v;
|
||||||
if (r.has_h()) result->height = r.vh.v;
|
if (r.has_h()) result->_height = r.vh.v;
|
||||||
if (r.has_duration()) result->duration = r.vduration.v;
|
if (r.has_duration()) result->_duration = r.vduration.v;
|
||||||
if (!result->thumb_url.isEmpty() && (result->thumb_url.startsWith(qstr("http://"), Qt::CaseInsensitive) || result->thumb_url.startsWith(qstr("https://"), Qt::CaseInsensitive))) {
|
if (!result->_thumb_url.isEmpty() && (result->_thumb_url.startsWith(qstr("http://"), Qt::CaseInsensitive) || result->_thumb_url.startsWith(qstr("https://"), Qt::CaseInsensitive))) {
|
||||||
result->thumb = ImagePtr(result->thumb_url);
|
result->_thumb = ImagePtr(result->_thumb_url);
|
||||||
}
|
}
|
||||||
message = &r.vsend_message;
|
message = &r.vsend_message;
|
||||||
} break;
|
} break;
|
||||||
case mtpc_botInlineMediaResult: {
|
case mtpc_botInlineMediaResult: {
|
||||||
const MTPDbotInlineMediaResult &r(mtpData.c_botInlineMediaResult());
|
const MTPDbotInlineMediaResult &r(mtpData.c_botInlineMediaResult());
|
||||||
result->id = qs(r.vid);
|
result->_id = qs(r.vid);
|
||||||
if (r.has_title()) result->title = qs(r.vtitle);
|
if (r.has_title()) result->_title = qs(r.vtitle);
|
||||||
if (r.has_description()) result->description = qs(r.vdescription);
|
if (r.has_description()) result->_description = qs(r.vdescription);
|
||||||
if (r.has_photo()) result->photo = App::feedPhoto(r.vphoto);
|
if (r.has_photo()) {
|
||||||
if (r.has_document()) result->document = App::feedDocument(r.vdocument);
|
result->_mtpPhoto = r.vphoto;
|
||||||
|
result->_photo = App::feedPhoto(r.vphoto);
|
||||||
|
}
|
||||||
|
if (r.has_document()) {
|
||||||
|
result->_mtpDocument = r.vdocument;
|
||||||
|
result->_document = App::feedDocument(r.vdocument);
|
||||||
|
}
|
||||||
message = &r.vsend_message;
|
message = &r.vsend_message;
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
bool badAttachment = (result->photo && !result->photo->access) || (result->document && !result->document->access);
|
bool badAttachment = (result->_photo && !result->_photo->access) || (result->_document && !result->_document->access);
|
||||||
|
|
||||||
if (!message) {
|
if (!message) {
|
||||||
return UniquePointer<Result>();
|
return UniquePointer<Result>();
|
||||||
|
@ -132,10 +133,10 @@ UniquePointer<Result> Result::create(uint64 queryId, const MTPBotInlineResult &m
|
||||||
switch (message->type()) {
|
switch (message->type()) {
|
||||||
case mtpc_botInlineMessageMediaAuto: {
|
case mtpc_botInlineMessageMediaAuto: {
|
||||||
const MTPDbotInlineMessageMediaAuto &r(message->c_botInlineMessageMediaAuto());
|
const MTPDbotInlineMessageMediaAuto &r(message->c_botInlineMessageMediaAuto());
|
||||||
if (result->type == Type::Photo) {
|
if (result->_type == Type::Photo) {
|
||||||
result->sendData.reset(new internal::SendPhoto(result->photo, result->content_url, qs(r.vcaption)));
|
result->sendData.reset(new internal::SendPhoto(result->_photo, result->_content_url, qs(r.vcaption)));
|
||||||
} else {
|
} else {
|
||||||
result->sendData.reset(new internal::SendFile(result->document, result->content_url, qs(r.vcaption)));
|
result->sendData.reset(new internal::SendFile(result->_document, result->_content_url, qs(r.vcaption)));
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
@ -176,11 +177,81 @@ UniquePointer<Result> Result::create(uint64 queryId, const MTPBotInlineResult &m
|
||||||
if (badAttachment || !result->sendData || !result->sendData->isValid()) {
|
if (badAttachment || !result->sendData || !result->sendData->isValid()) {
|
||||||
return UniquePointer<Result>();
|
return UniquePointer<Result>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LocationCoords location;
|
||||||
|
if (result->getLocationCoords(&location)) {
|
||||||
|
int32 w = st::inlineThumbSize, h = st::inlineThumbSize;
|
||||||
|
int32 zoom = 13, scale = 1;
|
||||||
|
if (cScale() == dbisTwo || cRetina()) {
|
||||||
|
scale = 2;
|
||||||
|
w /= 2;
|
||||||
|
h /= 2;
|
||||||
|
}
|
||||||
|
QString coords = qsl("%1,%2").arg(location.lat).arg(location.lon);
|
||||||
|
QString url = qsl("https://maps.googleapis.com/maps/api/staticmap?center=") + coords + qsl("&zoom=%1&size=%2x%3&maptype=roadmap&scale=%4&markers=color:red|size:big|").arg(zoom).arg(w).arg(h).arg(scale) + coords + qsl("&sensor=false");
|
||||||
|
result->_locationThumb = ImagePtr(url);
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Result::onChoose(Layout::ItemBase *layout) {
|
||||||
|
if (_photo && _type == Type::Photo) {
|
||||||
|
if (_photo->medium->loaded() || _photo->thumb->loaded()) {
|
||||||
|
return true;
|
||||||
|
} else if (!_photo->medium->loading()) {
|
||||||
|
_photo->thumb->loadEvenCancelled();
|
||||||
|
_photo->medium->loadEvenCancelled();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (_document && (
|
||||||
|
_type == Type::Video ||
|
||||||
|
_type == Type::Audio ||
|
||||||
|
_type == Type::Sticker ||
|
||||||
|
_type == Type::File ||
|
||||||
|
_type == Type::Gif)) {
|
||||||
|
if (_type == Type::Gif) {
|
||||||
|
if (_document->loaded()) {
|
||||||
|
return true;
|
||||||
|
} else if (_document->loading()) {
|
||||||
|
_document->cancel();
|
||||||
|
} else {
|
||||||
|
DocumentOpenClickHandler::doOpen(_document, ActionOnLoadNone);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (_type == Type::Photo) {
|
||||||
|
if (_thumb->loaded()) {
|
||||||
|
return true;
|
||||||
|
} else if (!_thumb->loading()) {
|
||||||
|
_thumb->loadEvenCancelled();
|
||||||
|
Ui::repaintInlineItem(layout);
|
||||||
|
}
|
||||||
|
} else if (_type == Type::Gif) {
|
||||||
|
if (loaded()) {
|
||||||
|
return true;
|
||||||
|
} else if (loading()) {
|
||||||
|
cancelFile();
|
||||||
|
Ui::repaintInlineItem(layout);
|
||||||
|
} else {
|
||||||
|
saveFile(QString(), LoadFromCloudOrLocal, false);
|
||||||
|
Ui::repaintInlineItem(layout);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void Result::automaticLoadGif() {
|
void Result::automaticLoadGif() {
|
||||||
if (loaded() || type != Type::Gif || (content_type != qstr("video/mp4") && content_type != "image/gif")) return;
|
if (loaded() || _type != Type::Gif) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (_content_type != qstr("video/mp4") && _content_type != qstr("image/gif")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (_loader != CancelledWebFileLoader) {
|
if (_loader != CancelledWebFileLoader) {
|
||||||
// if load at least anywhere
|
// if load at least anywhere
|
||||||
|
@ -191,7 +262,7 @@ void Result::automaticLoadGif() {
|
||||||
|
|
||||||
void Result::automaticLoadSettingsChangedGif() {
|
void Result::automaticLoadSettingsChangedGif() {
|
||||||
if (loaded() || _loader != CancelledWebFileLoader) return;
|
if (loaded() || _loader != CancelledWebFileLoader) return;
|
||||||
_loader = 0;
|
_loader = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Result::saveFile(const QString &toFile, LoadFromCloudSetting fromCloud, bool autoLoading) {
|
void Result::saveFile(const QString &toFile, LoadFromCloudSetting fromCloud, bool autoLoading) {
|
||||||
|
@ -199,18 +270,18 @@ void Result::saveFile(const QString &toFile, LoadFromCloudSetting fromCloud, boo
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_loader == CancelledWebFileLoader) _loader = 0;
|
if (_loader == CancelledWebFileLoader) _loader = nullptr;
|
||||||
if (_loader) {
|
if (_loader) {
|
||||||
if (!_loader->setFileName(toFile)) {
|
if (!_loader->setFileName(toFile)) {
|
||||||
cancelFile();
|
cancelFile();
|
||||||
_loader = 0;
|
_loader = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_loader) {
|
if (_loader) {
|
||||||
if (fromCloud == LoadFromCloudOrLocal) _loader->permitLoadFromCloud();
|
if (fromCloud == LoadFromCloudOrLocal) _loader->permitLoadFromCloud();
|
||||||
} else {
|
} else {
|
||||||
_loader = new webFileLoader(content_url, toFile, fromCloud, autoLoading);
|
_loader = new webFileLoader(_content_url, toFile, fromCloud, autoLoading);
|
||||||
regLoader(_loader, this);
|
regLoader(_loader, this);
|
||||||
|
|
||||||
_loader->connect(_loader, SIGNAL(progress(FileLoader*)), App::main(), SLOT(inlineResultLoadProgress(FileLoader*)));
|
_loader->connect(_loader, SIGNAL(progress(FileLoader*)), App::main(), SLOT(inlineResultLoadProgress(FileLoader*)));
|
||||||
|
@ -219,6 +290,80 @@ void Result::saveFile(const QString &toFile, LoadFromCloudSetting fromCloud, boo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Result::openFile() {
|
||||||
|
//if (loaded()) {
|
||||||
|
// bool playVoice = data->voice() && audioPlayer() && item;
|
||||||
|
// bool playMusic = data->song() && audioPlayer() && item;
|
||||||
|
// bool playAnimation = data->isAnimation() && item && item->getMedia();
|
||||||
|
// const FileLocation &location(data->location(true));
|
||||||
|
// if (!location.isEmpty() || (!data->data().isEmpty() && (playVoice || playMusic || playAnimation))) {
|
||||||
|
// if (playVoice) {
|
||||||
|
// AudioMsgId playing;
|
||||||
|
// AudioPlayerState playingState = AudioPlayerStopped;
|
||||||
|
// audioPlayer()->currentState(&playing, &playingState);
|
||||||
|
// if (playing.msgId == item->fullId() && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) {
|
||||||
|
// audioPlayer()->pauseresume(OverviewVoiceFiles);
|
||||||
|
// } else {
|
||||||
|
// AudioMsgId audio(data, item->fullId());
|
||||||
|
// audioPlayer()->play(audio);
|
||||||
|
// if (App::main()) {
|
||||||
|
// App::main()->audioPlayProgress(audio);
|
||||||
|
// App::main()->mediaMarkRead(data);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// } else if (playMusic) {
|
||||||
|
// SongMsgId playing;
|
||||||
|
// AudioPlayerState playingState = AudioPlayerStopped;
|
||||||
|
// audioPlayer()->currentState(&playing, &playingState);
|
||||||
|
// if (playing.msgId == item->fullId() && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) {
|
||||||
|
// audioPlayer()->pauseresume(OverviewFiles);
|
||||||
|
// } else {
|
||||||
|
// SongMsgId song(data, item->fullId());
|
||||||
|
// audioPlayer()->play(song);
|
||||||
|
// if (App::main()) App::main()->documentPlayProgress(song);
|
||||||
|
// }
|
||||||
|
// } else if (data->voice() || data->isVideo()) {
|
||||||
|
// psOpenFile(location.name());
|
||||||
|
// if (App::main()) App::main()->mediaMarkRead(data);
|
||||||
|
// } else if (data->size < MediaViewImageSizeLimit) {
|
||||||
|
// if (!data->data().isEmpty() && playAnimation) {
|
||||||
|
// if (action == ActionOnLoadPlayInline && item->getMedia()) {
|
||||||
|
// item->getMedia()->playInline(item);
|
||||||
|
// } else {
|
||||||
|
// App::wnd()->showDocument(data, item);
|
||||||
|
// }
|
||||||
|
// } else if (location.accessEnable()) {
|
||||||
|
// if (item && (data->isAnimation() || QImageReader(location.name()).canRead())) {
|
||||||
|
// if (action == ActionOnLoadPlayInline && item->getMedia()) {
|
||||||
|
// item->getMedia()->playInline(item);
|
||||||
|
// } else {
|
||||||
|
// App::wnd()->showDocument(data, item);
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// psOpenFile(location.name());
|
||||||
|
// }
|
||||||
|
// location.accessDisable();
|
||||||
|
// } else {
|
||||||
|
// psOpenFile(location.name());
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// psOpenFile(location.name());
|
||||||
|
// }
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
//QString filename = documentSaveFilename(data);
|
||||||
|
//if (filename.isEmpty()) return;
|
||||||
|
//if (!data->saveToCache()) {
|
||||||
|
// filename = documentSaveFilename(data);
|
||||||
|
// if (filename.isEmpty()) return;
|
||||||
|
//}
|
||||||
|
|
||||||
|
//saveFile()
|
||||||
|
//data->save(filename, action, item ? item->fullId() : FullMsgId());
|
||||||
|
}
|
||||||
|
|
||||||
void Result::cancelFile() {
|
void Result::cancelFile() {
|
||||||
if (!loading()) return;
|
if (!loading()) return;
|
||||||
|
|
||||||
|
@ -254,7 +399,7 @@ bool Result::loaded() const {
|
||||||
|
|
||||||
_loader->deleteLater();
|
_loader->deleteLater();
|
||||||
_loader->stop();
|
_loader->stop();
|
||||||
_loader = 0;
|
_loader = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return !_data.isEmpty();
|
return !_data.isEmpty();
|
||||||
|
@ -265,8 +410,14 @@ bool Result::displayLoading() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Result::forget() {
|
void Result::forget() {
|
||||||
thumb->forget();
|
_thumb->forget();
|
||||||
_data.clear();
|
_data.clear();
|
||||||
|
if (_document) {
|
||||||
|
_document->forget();
|
||||||
|
}
|
||||||
|
if (_photo) {
|
||||||
|
_photo->forget();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float64 Result::progress() const {
|
float64 Result::progress() const {
|
||||||
|
@ -274,10 +425,10 @@ float64 Result::progress() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Result::hasThumbDisplay() const {
|
bool Result::hasThumbDisplay() const {
|
||||||
if (!thumb->isNull()) {
|
if (!_thumb->isNull()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (type == Type::Contact) {
|
if (_type == Type::Contact) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (sendData->hasLocationCoords()) {
|
if (sendData->hasLocationCoords()) {
|
||||||
|
|
|
@ -42,18 +42,6 @@ private:
|
||||||
struct Creator;
|
struct Creator;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum class Type {
|
|
||||||
Unknown,
|
|
||||||
Photo,
|
|
||||||
Video,
|
|
||||||
Audio,
|
|
||||||
Sticker,
|
|
||||||
File,
|
|
||||||
Gif,
|
|
||||||
Article,
|
|
||||||
Contact,
|
|
||||||
Venue,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Constructor is public only for MakeUnique<>() to work.
|
// Constructor is public only for MakeUnique<>() to work.
|
||||||
// You should use create() static method instead.
|
// You should use create() static method instead.
|
||||||
|
@ -62,22 +50,21 @@ public:
|
||||||
Result(const Result &other) = delete;
|
Result(const Result &other) = delete;
|
||||||
Result &operator=(const Result &other) = delete;
|
Result &operator=(const Result &other) = delete;
|
||||||
|
|
||||||
uint64 queryId;
|
uint64 getQueryId() const {
|
||||||
QString id;
|
return _queryId;
|
||||||
Type type;
|
}
|
||||||
DocumentData *document = nullptr;
|
QString getId() const {
|
||||||
PhotoData *photo = nullptr;
|
return _id;
|
||||||
QString title, description, url, thumb_url;
|
}
|
||||||
QString content_type, content_url;
|
|
||||||
int width = 0;
|
|
||||||
int height = 0;
|
|
||||||
int duration = 0;
|
|
||||||
|
|
||||||
ImagePtr thumb;
|
// This is real SendClickHandler::onClick implementation for the specified
|
||||||
|
// inline bot result. If it returns true you need to send this result.
|
||||||
|
bool onChoose(Layout::ItemBase *layout);
|
||||||
|
|
||||||
void automaticLoadGif();
|
void automaticLoadGif();
|
||||||
void automaticLoadSettingsChangedGif();
|
void automaticLoadSettingsChangedGif();
|
||||||
void saveFile(const QString &toFile, LoadFromCloudSetting fromCloud, bool autoLoading);
|
void saveFile(const QString &toFile, LoadFromCloudSetting fromCloud, bool autoLoading);
|
||||||
|
void openFile();
|
||||||
void cancelFile();
|
void cancelFile();
|
||||||
|
|
||||||
QByteArray data() const;
|
QByteArray data() const;
|
||||||
|
@ -99,11 +86,43 @@ public:
|
||||||
~Result();
|
~Result();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
enum class Type {
|
||||||
|
Unknown,
|
||||||
|
Photo,
|
||||||
|
Video,
|
||||||
|
Audio,
|
||||||
|
Sticker,
|
||||||
|
File,
|
||||||
|
Gif,
|
||||||
|
Article,
|
||||||
|
Contact,
|
||||||
|
Venue,
|
||||||
|
};
|
||||||
|
|
||||||
|
friend class internal::SendData;
|
||||||
|
friend class Layout::ItemBase;
|
||||||
struct Creator {
|
struct Creator {
|
||||||
uint64 queryId;
|
uint64 queryId;
|
||||||
Type type;
|
Type type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
uint64 _queryId = 0;
|
||||||
|
QString _id;
|
||||||
|
Type _type = Type::Unknown;
|
||||||
|
QString _title, _description, _url, _thumb_url;
|
||||||
|
QString _content_type, _content_url;
|
||||||
|
int _width = 0;
|
||||||
|
int _height = 0;
|
||||||
|
int _duration = 0;
|
||||||
|
|
||||||
|
mutable MTPDocument _mtpDocument = MTP_documentEmpty(MTP_long(0));
|
||||||
|
DocumentData *_document = nullptr;
|
||||||
|
|
||||||
|
mutable MTPPhoto _mtpPhoto = MTP_photoEmpty(MTP_long(0));
|
||||||
|
PhotoData *_photo = nullptr;
|
||||||
|
|
||||||
|
ImagePtr _thumb, _locationThumb;
|
||||||
|
|
||||||
UniquePointer<internal::SendData> sendData;
|
UniquePointer<internal::SendData> sendData;
|
||||||
|
|
||||||
QByteArray _data;
|
QByteArray _data;
|
||||||
|
|
|
@ -28,11 +28,59 @@ namespace InlineBots {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
QString SendData::getLayoutTitle(const Result *owner) const {
|
QString SendData::getLayoutTitle(const Result *owner) const {
|
||||||
return owner->title;
|
return owner->_title;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString SendData::getLayoutDescription(const Result *owner) const {
|
QString SendData::getLayoutDescription(const Result *owner) const {
|
||||||
return owner->description;
|
return owner->_description;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImagePtr SendData::getResultThumb(const Result *owner) const {
|
||||||
|
return owner->_thumb;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SendData::getResultWidth(const Result *owner) const {
|
||||||
|
return owner->_width;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SendData::getResultHeight(const Result *owner) const {
|
||||||
|
return owner->_height;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString SendData::getResultMime(const Result *owner) const {
|
||||||
|
return owner->_content_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVector<MTPDocumentAttribute> SendData::prepareResultAttributes(const Result *owner) const {
|
||||||
|
QVector<MTPDocumentAttribute> result;
|
||||||
|
int duration = owner->_duration;
|
||||||
|
QSize dimensions(owner->_width, owner->_height);
|
||||||
|
using Type = Result::Type;
|
||||||
|
if (owner->_type == Type::Gif) {
|
||||||
|
const char *filename = (owner->_content_type == qstr("video/mp4") ? "animation.gif.mp4" : "animation.gif");
|
||||||
|
result.push_back(MTP_documentAttributeFilename(MTP_string(filename)));
|
||||||
|
result.push_back(MTP_documentAttributeAnimated());
|
||||||
|
result.push_back(MTP_documentAttributeVideo(MTP_int(owner->_duration), MTP_int(owner->_width), MTP_int(owner->_height)));
|
||||||
|
} else if (owner->_type == Type::Video) {
|
||||||
|
result.push_back(MTP_documentAttributeVideo(MTP_int(owner->_duration), MTP_int(owner->_width), MTP_int(owner->_height)));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SendData::setResultDocument(const Result *owner, const MTPDocument &document) const {
|
||||||
|
owner->_mtpDocument = document;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SendData::setResultPhoto(const Result *owner, const MTPPhoto &photo) const {
|
||||||
|
owner->_mtpPhoto = photo;
|
||||||
|
}
|
||||||
|
|
||||||
|
MTPDocument SendData::getResultDocument(const Result *owner) const {
|
||||||
|
return owner->_mtpDocument;
|
||||||
|
}
|
||||||
|
|
||||||
|
MTPPhoto SendData::getResultPhoto(const Result *owner) const {
|
||||||
|
return owner->_mtpPhoto;
|
||||||
}
|
}
|
||||||
|
|
||||||
SendData::SentMTPMessageFields SendText::getSentMessageFields(const Result*) const {
|
SendData::SentMTPMessageFields SendText::getSentMessageFields(const Result*) const {
|
||||||
|
@ -61,13 +109,14 @@ SendData::SentMTPMessageFields SendContact::getSentMessageFields(const Result*)
|
||||||
}
|
}
|
||||||
|
|
||||||
QString SendContact::getLayoutDescription(const Result *owner) const {
|
QString SendContact::getLayoutDescription(const Result *owner) const {
|
||||||
return App::formatPhone(_phoneNumber) + '\n' + owner->description;
|
return App::formatPhone(_phoneNumber) + '\n' + SendData::getLayoutDescription(owner);
|
||||||
}
|
}
|
||||||
|
|
||||||
SendData::SentMTPMessageFields SendPhoto::getSentMessageFields(const Result *owner) const {
|
SendData::SentMTPMessageFields SendPhoto::getSentMessageFields(const Result *owner) const {
|
||||||
SentMTPMessageFields result;
|
SentMTPMessageFields result;
|
||||||
|
|
||||||
QImage fileThumb(owner->thumb->pix().toImage());
|
ImagePtr resultThumb = getResultThumb(owner);
|
||||||
|
QImage fileThumb(resultThumb->pix().toImage());
|
||||||
|
|
||||||
QVector<MTPPhotoSize> photoSizes;
|
QVector<MTPPhotoSize> photoSizes;
|
||||||
|
|
||||||
|
@ -75,13 +124,13 @@ SendData::SentMTPMessageFields SendPhoto::getSentMessageFields(const Result *own
|
||||||
ImagePtr thumbPtr = ImagePtr(thumb, "JPG");
|
ImagePtr thumbPtr = ImagePtr(thumb, "JPG");
|
||||||
photoSizes.push_back(MTP_photoSize(MTP_string("s"), MTP_fileLocationUnavailable(MTP_long(0), MTP_int(0), MTP_long(0)), MTP_int(thumb.width()), MTP_int(thumb.height()), MTP_int(0)));
|
photoSizes.push_back(MTP_photoSize(MTP_string("s"), MTP_fileLocationUnavailable(MTP_long(0), MTP_int(0), MTP_long(0)), MTP_int(thumb.width()), MTP_int(thumb.height()), MTP_int(0)));
|
||||||
|
|
||||||
QSize medium = resizeKeepAspect(owner->width, owner->height, 320, 320);
|
QSize medium = resizeKeepAspect(getResultWidth(owner), getResultHeight(owner), 320, 320);
|
||||||
photoSizes.push_back(MTP_photoSize(MTP_string("m"), MTP_fileLocationUnavailable(MTP_long(0), MTP_int(0), MTP_long(0)), MTP_int(medium.width()), MTP_int(medium.height()), MTP_int(0)));
|
photoSizes.push_back(MTP_photoSize(MTP_string("m"), MTP_fileLocationUnavailable(MTP_long(0), MTP_int(0), MTP_long(0)), MTP_int(medium.width()), MTP_int(medium.height()), MTP_int(0)));
|
||||||
|
|
||||||
photoSizes.push_back(MTP_photoSize(MTP_string("x"), MTP_fileLocationUnavailable(MTP_long(0), MTP_int(0), MTP_long(0)), MTP_int(owner->width), MTP_int(owner->height), MTP_int(0)));
|
photoSizes.push_back(MTP_photoSize(MTP_string("x"), MTP_fileLocationUnavailable(MTP_long(0), MTP_int(0), MTP_long(0)), MTP_int(getResultWidth(owner)), MTP_int(getResultHeight(owner)), MTP_int(0)));
|
||||||
|
|
||||||
uint64 photoId = rand_value<uint64>();
|
uint64 photoId = rand_value<uint64>();
|
||||||
PhotoData *ph = App::photoSet(photoId, 0, 0, unixtime(), thumbPtr, ImagePtr(medium.width(), medium.height()), ImagePtr(owner->width, owner->height));
|
PhotoData *ph = App::photoSet(photoId, 0, 0, unixtime(), thumbPtr, ImagePtr(medium.width(), medium.height()), ImagePtr(getResultWidth(owner), getResultHeight(owner)));
|
||||||
MTPPhoto photo = MTP_photo(MTP_long(photoId), MTP_long(0), MTP_int(ph->date), MTP_vector<MTPPhotoSize>(photoSizes));
|
MTPPhoto photo = MTP_photo(MTP_long(photoId), MTP_long(0), MTP_int(ph->date), MTP_vector<MTPPhotoSize>(photoSizes));
|
||||||
|
|
||||||
result.media = MTP_messageMediaPhoto(photo, MTP_string(_caption));
|
result.media = MTP_messageMediaPhoto(photo, MTP_string(_caption));
|
||||||
|
@ -89,13 +138,14 @@ SendData::SentMTPMessageFields SendPhoto::getSentMessageFields(const Result *own
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
SendData::SentMTPMessageFields SendFile::getSentMessageFields(const Result *owner) const {
|
void SendFile::prepareDocument(const Result *owner) const {
|
||||||
SentMTPMessageFields result;
|
if (getResultDocument(owner).type() != mtpc_documentEmpty) return;
|
||||||
|
|
||||||
|
ImagePtr resultThumb = getResultThumb(owner);
|
||||||
MTPPhotoSize thumbSize;
|
MTPPhotoSize thumbSize;
|
||||||
QPixmap thumb;
|
QPixmap thumb;
|
||||||
int32 tw = owner->thumb->width(), th = owner->thumb->height();
|
int32 tw = resultThumb->width(), th = resultThumb->height();
|
||||||
if (tw > 0 && th > 0 && tw < 20 * th && th < 20 * tw && owner->thumb->loaded()) {
|
if (tw > 0 && th > 0 && tw < 20 * th && th < 20 * tw && resultThumb->loaded()) {
|
||||||
if (tw > th) {
|
if (tw > th) {
|
||||||
if (tw > 90) {
|
if (tw > 90) {
|
||||||
th = th * 90 / tw;
|
th = th * 90 / tw;
|
||||||
|
@ -106,41 +156,34 @@ SendData::SentMTPMessageFields SendFile::getSentMessageFields(const Result *owne
|
||||||
th = 90;
|
th = 90;
|
||||||
}
|
}
|
||||||
thumbSize = MTP_photoSize(MTP_string(""), MTP_fileLocationUnavailable(MTP_long(0), MTP_int(0), MTP_long(0)), MTP_int(tw), MTP_int(th), MTP_int(0));
|
thumbSize = MTP_photoSize(MTP_string(""), MTP_fileLocationUnavailable(MTP_long(0), MTP_int(0), MTP_long(0)), MTP_int(tw), MTP_int(th), MTP_int(0));
|
||||||
thumb = owner->thumb->pixNoCache(tw, th, ImagePixSmooth);
|
thumb = resultThumb->pixNoCache(tw, th, ImagePixSmooth);
|
||||||
} else {
|
} else {
|
||||||
tw = th = 0;
|
tw = th = 0;
|
||||||
thumbSize = MTP_photoSizeEmpty(MTP_string(""));
|
thumbSize = MTP_photoSizeEmpty(MTP_string(""));
|
||||||
}
|
}
|
||||||
uint64 docId = rand_value<uint64>();
|
uint64 docId = rand_value<uint64>();
|
||||||
QVector<MTPDocumentAttribute> attributes;
|
|
||||||
|
|
||||||
int duration = getSentDuration(owner);
|
QVector<MTPDocumentAttribute> attributes = prepareResultAttributes(owner);
|
||||||
QSize dimensions = getSentDimensions(owner);
|
MTPDocument document = MTP_document(MTP_long(docId), MTP_long(0), MTP_int(unixtime()), MTP_string(getResultMime(owner)), MTP_int(owner->data().size()), thumbSize, MTP_int(MTP::maindc()), MTP_vector<MTPDocumentAttribute>(attributes));
|
||||||
using Type = Result::Type;
|
|
||||||
if (owner->type == Type::Gif) {
|
|
||||||
attributes.push_back(MTP_documentAttributeFilename(MTP_string((owner->content_type == qstr("video/mp4") ? "animation.gif.mp4" : "animation.gif"))));
|
|
||||||
attributes.push_back(MTP_documentAttributeAnimated());
|
|
||||||
attributes.push_back(MTP_documentAttributeVideo(MTP_int(duration), MTP_int(dimensions.width()), MTP_int(dimensions.height())));
|
|
||||||
} else if (owner->type == Type::Video) {
|
|
||||||
attributes.push_back(MTP_documentAttributeVideo(MTP_int(duration), MTP_int(dimensions.width()), MTP_int(dimensions.height())));
|
|
||||||
}
|
|
||||||
MTPDocument document = MTP_document(MTP_long(docId), MTP_long(0), MTP_int(unixtime()), MTP_string(owner->content_type), MTP_int(owner->data().size()), thumbSize, MTP_int(MTP::maindc()), MTP_vector<MTPDocumentAttribute>(attributes));
|
|
||||||
if (tw > 0 && th > 0) {
|
if (tw > 0 && th > 0) {
|
||||||
App::feedDocument(document, thumb);
|
App::feedDocument(document, thumb);
|
||||||
}
|
}
|
||||||
|
if (!owner->data().isEmpty()) {
|
||||||
Local::writeStickerImage(mediaKey(DocumentFileLocation, MTP::maindc(), docId), owner->data());
|
Local::writeStickerImage(mediaKey(DocumentFileLocation, MTP::maindc(), docId), owner->data());
|
||||||
|
}
|
||||||
|
setResultDocument(owner, document);
|
||||||
|
}
|
||||||
|
|
||||||
|
SendData::SentMTPMessageFields SendFile::getSentMessageFields(const Result *owner) const {
|
||||||
|
SentMTPMessageFields result;
|
||||||
|
|
||||||
|
prepareDocument(owner);
|
||||||
|
|
||||||
|
MTPDocument document = getResultDocument(owner);
|
||||||
result.media = MTP_messageMediaDocument(document, MTP_string(_caption));
|
result.media = MTP_messageMediaDocument(document, MTP_string(_caption));
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SendFile::getSentDuration(const Result *owner) const {
|
|
||||||
return (_document && _document->duration()) ? _document->duration() : owner->duration;
|
|
||||||
}
|
|
||||||
QSize SendFile::getSentDimensions(const Result *owner) const {
|
|
||||||
return (!_document || _document->dimensions.isEmpty()) ? QSize(owner->width, owner->height) : _document->dimensions;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
} // namespace InlineBots
|
} // namespace InlineBots
|
||||||
|
|
|
@ -67,6 +67,20 @@ public:
|
||||||
virtual QString getLayoutTitle(const Result *owner) const;
|
virtual QString getLayoutTitle(const Result *owner) const;
|
||||||
virtual QString getLayoutDescription(const Result *owner) const;
|
virtual QString getLayoutDescription(const Result *owner) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
ImagePtr getResultThumb(const Result *owner) const;
|
||||||
|
int getResultWidth(const Result *owner) const;
|
||||||
|
int getResultHeight(const Result *owner) const;
|
||||||
|
QString getResultMime(const Result *owner) const;
|
||||||
|
QVector<MTPDocumentAttribute> prepareResultAttributes(const Result *owner) const;
|
||||||
|
|
||||||
|
void setResultDocument(const Result *owner, const MTPDocument &document) const;
|
||||||
|
void setResultPhoto(const Result *owner, const MTPPhoto &photo) const;
|
||||||
|
|
||||||
|
MTPDocument getResultDocument(const Result *owner) const;
|
||||||
|
MTPPhoto getResultPhoto(const Result *owner) const;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Plain text message.
|
// Plain text message.
|
||||||
|
@ -221,12 +235,11 @@ public:
|
||||||
SentMTPMessageFields getSentMessageFields(const Result *owner) const override;
|
SentMTPMessageFields getSentMessageFields(const Result *owner) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void prepareDocument(const Result *owner) const;
|
||||||
|
|
||||||
DocumentData *_document;
|
DocumentData *_document;
|
||||||
QString _url, _caption;
|
QString _url, _caption;
|
||||||
|
|
||||||
int getSentDuration(const Result *owner) const;
|
|
||||||
QSize getSentDimensions(const Result *owner) const;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
|
Loading…
Reference in New Issue