mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-03-30 07:18:28 +00:00
added webvideo and article layouts for inline bots
This commit is contained in:
parent
5830e0f657
commit
945d9b1883
Telegram
@ -1991,11 +1991,6 @@ stickerPreviewDuration: 150;
|
||||
stickerPreviewBg: #FFFFFFB0;
|
||||
stickerPreviewMin: 0.1;
|
||||
|
||||
inlineResultsLeft: 15px;
|
||||
inlineResultsSkip: 3px;
|
||||
inlineMediaHeight: 96px;
|
||||
inlineResultsMinWidth: 64px;
|
||||
|
||||
verifiedCheckProfile: sprite(285px, 235px, 18px, 18px);
|
||||
verifiedCheckProfilePos: point(7px, 6px);
|
||||
verifiedCheck: sprite(285px, 221px, 14px, 14px);
|
||||
@ -2346,9 +2341,21 @@ linksMaxWidth: 520px;
|
||||
linksLetterFont: font(24px);
|
||||
linksMargin: 5px;
|
||||
linksBorder: 1px;
|
||||
linksBorderColor: #eaeaea;
|
||||
linksBorderFg: #eaeaea;
|
||||
linksDateColor: #000;
|
||||
linksDateMargin: 15px;
|
||||
|
||||
linksPhotoCheck: sprite(184px, 196px, 16px, 16px);
|
||||
linksPhotoChecked: sprite(168px, 196px, 16px, 16px);
|
||||
|
||||
inlineResultsLeft: 15px;
|
||||
inlineResultsSkip: 3px;
|
||||
inlineMediaHeight: 96px;
|
||||
inlineThumbSize: 64px;
|
||||
inlineThumbSkip: 10px;
|
||||
inlineDescriptionFg: #8a8a8a;
|
||||
inlineRowMargin: 6px;
|
||||
inlineRowBorder: linksBorder;
|
||||
inlineRowBorderFg: linksBorderFg;
|
||||
inlineResultsMinWidth: 64px;
|
||||
inlineDurationMargin: 3px;
|
||||
|
@ -1216,6 +1216,7 @@ StickerPanInner::StickerPanInner() : TWidget()
|
||||
, _showingSavedGifs(cShowingSavedGifs())
|
||||
, _showingInlineItems(_showingSavedGifs)
|
||||
, _lastScrolled(0)
|
||||
, _inlineWithThumb(false)
|
||||
, _selected(-1)
|
||||
, _pressedSel(-1)
|
||||
, _settings(this, lang(lng_stickers_you_have))
|
||||
@ -1301,7 +1302,7 @@ void StickerPanInner::paintEvent(QPaintEvent *e) {
|
||||
}
|
||||
|
||||
void StickerPanInner::paintInlineItems(Painter &p, const QRect &r) {
|
||||
InlinePaintContext context(getms(), false, _previewShown);
|
||||
InlinePaintContext context(getms(), false, _previewShown, false);
|
||||
|
||||
int32 top = st::emojiPanHeader;
|
||||
int32 fromx = rtl() ? (width() - r.x() - r.width()) : r.x(), tox = rtl() ? (width() - r.x()) : (r.x() + r.width());
|
||||
@ -1310,6 +1311,7 @@ void StickerPanInner::paintInlineItems(Painter &p, const QRect &r) {
|
||||
if (top >= r.top() + r.height()) break;
|
||||
if (top + inlineRow.height > r.top()) {
|
||||
int32 left = st::inlineResultsLeft;
|
||||
if (row == rows - 1) context.lastRow = true;
|
||||
for (int32 col = 0, cols = inlineRow.items.size(); col < cols; ++col) {
|
||||
if (left >= tox) break;
|
||||
|
||||
@ -1750,9 +1752,9 @@ LayoutInlineItem *StickerPanInner::layoutPrepareInlineResult(InlineResult *resul
|
||||
} else if (result->type == qstr("photo")) {
|
||||
layout = new LayoutInlinePhoto(result, 0);
|
||||
} else if (result->type == qstr("web_player_video")) {
|
||||
// layout = new LayoutInlineWebVideo(result, 0);
|
||||
layout = new LayoutInlineWebVideo(result);
|
||||
} else if (result->type == qstr("article")) {
|
||||
// layout = new LayoutInlineArticle(result, 0);
|
||||
layout = new LayoutInlineArticle(result, _inlineWithThumb);
|
||||
}
|
||||
if (!layout) return 0;
|
||||
|
||||
@ -1927,6 +1929,16 @@ void StickerPanInner::refreshInlineRows(UserData *bot, const InlineResults &resu
|
||||
}
|
||||
_inlineRows.resize(untilrow);
|
||||
|
||||
if (_inlineRows.isEmpty()) {
|
||||
_inlineWithThumb = false;
|
||||
for (int32 i = until; i < count; ++i) {
|
||||
if (!results.at(i)->thumb->isNull()) {
|
||||
_inlineWithThumb = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_inlineRows.reserve(count);
|
||||
InlineRow row;
|
||||
row.items.reserve(SavedGifsMaxPerRow);
|
||||
@ -3072,6 +3084,10 @@ void EmojiPan::step_appearance(float64 ms, bool timer) {
|
||||
void EmojiPan::hideStart() {
|
||||
if (_removingSetId || s_inner.inlineResultsShown()) return;
|
||||
|
||||
hideAnimated();
|
||||
}
|
||||
|
||||
void EmojiPan::hideAnimated() {
|
||||
if (_cache.isNull()) {
|
||||
QPixmap from = _fromCache, to = _toCache;
|
||||
_fromCache = _toCache = QPixmap();
|
||||
@ -3412,7 +3428,7 @@ void EmojiPan::onDelayedHide() {
|
||||
void EmojiPan::inlineBotChanged() {
|
||||
if (!_inlineBot) return;
|
||||
|
||||
if (!isHidden()) hideStart();
|
||||
if (!isHidden()) hideAnimated();
|
||||
|
||||
if (_inlineRequestId) MTP::cancel(_inlineRequestId);
|
||||
_inlineRequestId = 0;
|
||||
@ -3572,7 +3588,7 @@ void EmojiPan::showInlineRows(bool newResults) {
|
||||
s_inner.refreshInlineRows(_inlineBot, clear ? InlineResults() : i.value()->results, false);
|
||||
if (newResults) s_scroll.scrollToY(0);
|
||||
if (clear && !isHidden() && _stickersShown && s_inner.inlineResultsShown()) {
|
||||
hideStart();
|
||||
hideAnimated();
|
||||
} else if (!clear) {
|
||||
_hideTimer.stop();
|
||||
if (!isHidden() || _hiding) {
|
||||
|
@ -430,6 +430,7 @@ private:
|
||||
QString _inlineBotTitle;
|
||||
uint64 _lastScrolled;
|
||||
QTimer _updateInlineItems;
|
||||
bool _inlineWithThumb;
|
||||
|
||||
typedef QVector<LayoutInlineItem*> InlineItems;
|
||||
struct InlineRow {
|
||||
@ -617,6 +618,7 @@ private:
|
||||
bool _horizontal;
|
||||
|
||||
void leaveToChildEvent(QEvent *e);
|
||||
void hideAnimated();
|
||||
|
||||
void updateSelected();
|
||||
void updateIcons();
|
||||
|
@ -1031,6 +1031,9 @@ public:
|
||||
_y = top;
|
||||
_yFrom = yFrom + top;
|
||||
_yTo = (yTo < 0) ? -1 : (yTo + top);
|
||||
if (_elideLast) {
|
||||
_yToElide = _yTo;
|
||||
}
|
||||
_selectedFrom = selectedFrom;
|
||||
_selectedTo = selectedTo;
|
||||
_wLeft = _w = w;
|
||||
@ -1081,7 +1084,7 @@ public:
|
||||
last_rBearing = _rb;
|
||||
last_rPadding = b->f_rpadding();
|
||||
_wLeft = _w - (b->f_width() - last_rBearing);
|
||||
if (_elideLast && _elideRemoveFromEnd > 0 && (_y + blockHeight >= _yTo)) {
|
||||
if (_elideLast && _elideRemoveFromEnd > 0 && (_y + blockHeight >= _yToElide)) {
|
||||
_wLeft -= _elideRemoveFromEnd;
|
||||
}
|
||||
|
||||
@ -1135,7 +1138,7 @@ public:
|
||||
}
|
||||
|
||||
int32 elidedLineHeight = qMax(_lineHeight, blockHeight);
|
||||
bool elidedLine = _elideLast && (_y + elidedLineHeight >= _yTo);
|
||||
bool elidedLine = _elideLast && (_y + elidedLineHeight >= _yToElide);
|
||||
if (elidedLine) {
|
||||
_lineHeight = elidedLineHeight;
|
||||
} else if (f != j) {
|
||||
@ -1154,7 +1157,7 @@ public:
|
||||
last_rBearing = j->f_rbearing();
|
||||
last_rPadding = j->rpadding;
|
||||
_wLeft = _w - (j_width - last_rBearing);
|
||||
if (_elideLast && _elideRemoveFromEnd > 0 && (_y + blockHeight >= _yTo)) {
|
||||
if (_elideLast && _elideRemoveFromEnd > 0 && (_y + blockHeight >= _yToElide)) {
|
||||
_wLeft -= _elideRemoveFromEnd;
|
||||
}
|
||||
|
||||
@ -1165,7 +1168,7 @@ public:
|
||||
}
|
||||
if (lpadding > 0) { // no words in this block, spaces only
|
||||
int32 elidedLineHeight = qMax(_lineHeight, blockHeight);
|
||||
bool elidedLine = _elideLast && (_y + elidedLineHeight >= _yTo);
|
||||
bool elidedLine = _elideLast && (_y + elidedLineHeight >= _yToElide);
|
||||
if (elidedLine) {
|
||||
_lineHeight = elidedLineHeight;
|
||||
}
|
||||
@ -1179,7 +1182,7 @@ public:
|
||||
last_rBearing = _rb;
|
||||
last_rPadding = b->rpadding();
|
||||
_wLeft = _w;
|
||||
if (_elideLast && _elideRemoveFromEnd > 0 && (_y + blockHeight >= _yTo)) {
|
||||
if (_elideLast && _elideRemoveFromEnd > 0 && (_y + blockHeight >= _yToElide)) {
|
||||
_wLeft -= _elideRemoveFromEnd;
|
||||
}
|
||||
|
||||
@ -1189,7 +1192,7 @@ public:
|
||||
}
|
||||
|
||||
int32 elidedLineHeight = qMax(_lineHeight, blockHeight);
|
||||
bool elidedLine = _elideLast && (_y + elidedLineHeight >= _yTo);
|
||||
bool elidedLine = _elideLast && (_y + elidedLineHeight >= _yToElide);
|
||||
if (elidedLine) {
|
||||
_lineHeight = elidedLineHeight;
|
||||
}
|
||||
@ -1202,7 +1205,7 @@ public:
|
||||
last_rBearing = _rb;
|
||||
last_rPadding = b->f_rpadding();
|
||||
_wLeft = _w - (b->f_width() - last_rBearing);
|
||||
if (_elideLast && _elideRemoveFromEnd > 0 && (_y + blockHeight >= _yTo)) {
|
||||
if (_elideLast && _elideRemoveFromEnd > 0 && (_y + blockHeight >= _yToElide)) {
|
||||
_wLeft -= _elideRemoveFromEnd;
|
||||
}
|
||||
|
||||
@ -1301,7 +1304,7 @@ public:
|
||||
}
|
||||
|
||||
ITextBlock *_endBlock = (_endBlockIter == _end) ? 0 : (*_endBlockIter);
|
||||
bool elidedLine = _elideLast && _endBlock && (_y + _lineHeight >= _yTo);
|
||||
bool elidedLine = _elideLast && _endBlock && (_y + _lineHeight >= _yToElide);
|
||||
|
||||
int blockIndex = _lineStartBlock;
|
||||
ITextBlock *currentBlock = _t->_blocks[blockIndex];
|
||||
@ -2409,7 +2412,7 @@ private:
|
||||
int32 _elideRemoveFromEnd;
|
||||
style::align _align;
|
||||
QPen _originalPen;
|
||||
int32 _yFrom, _yTo;
|
||||
int32 _yFrom, _yTo, _yToElide;
|
||||
uint16 _selectedFrom, _selectedTo;
|
||||
const QChar *_str;
|
||||
|
||||
|
@ -4345,9 +4345,8 @@ void HistoryWidget::onSend(bool ctrlShiftEnter, MsgId replyTo) {
|
||||
_saveDraftStart = getms();
|
||||
onDraftSave();
|
||||
|
||||
if (!_attachMention.isHidden()) _attachMention.hideStart();
|
||||
onCheckMentionDropdown();
|
||||
if (!_attachType.isHidden()) _attachType.hideStart();
|
||||
if (!_emojiPan.isHidden()) _emojiPan.hideStart();
|
||||
|
||||
if (replyTo < 0) cancelReply(lastKeyboardUsed);
|
||||
if (_previewData && _previewData->pendingTill) previewCancel();
|
||||
@ -6357,6 +6356,7 @@ void HistoryWidget::onInlineResultSend(InlineResult *result, UserData *bot) {
|
||||
_history->addNewMessage(MTP_message(MTP_int(flags), MTP_int(newId.msg), MTP_int(fromChannelName ? 0 : MTP::authedId()), peerToMTP(_history->peer->id), MTPPeer(), MTPint(), MTP_int(bot ? peerToUser(bot->id) : 0), MTP_int(replyToId()), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaPhoto(photo, MTP_string(result->caption)), MTPnullMarkup, MTPnullEntities, MTP_int(1)), NewMessageUnread);
|
||||
}
|
||||
} else {
|
||||
flags |= MTPDmessage::flag_entities;
|
||||
if (result->noWebPage) {
|
||||
sendFlags |= MTPmessages_SendMessage::flag_no_webpage;
|
||||
}
|
||||
@ -6373,9 +6373,8 @@ void HistoryWidget::onInlineResultSend(InlineResult *result, UserData *bot) {
|
||||
_saveDraftStart = getms();
|
||||
onDraftSave();
|
||||
|
||||
if (!_attachMention.isHidden()) _attachMention.hideStart();
|
||||
onCheckMentionDropdown();
|
||||
if (!_attachType.isHidden()) _attachType.hideStart();
|
||||
if (!_emojiPan.isHidden()) _emojiPan.hideStart();
|
||||
|
||||
_field.setFocus();
|
||||
}
|
||||
|
@ -824,7 +824,7 @@ void LayoutOverviewDocument::paint(Painter &p, const QRect &clip, uint32 selecti
|
||||
|
||||
QRect shadow(rtlrect(nameleft, 0, _width - nameleft, st::linksBorder, _width));
|
||||
if (clip.intersects(shadow)) {
|
||||
p.fillRect(clip.intersected(shadow), st::linksBorderColor);
|
||||
p.fillRect(clip.intersected(shadow), st::linksBorderFg);
|
||||
}
|
||||
|
||||
QRect rthumb(rtlrect(0, st::linksBorder + st::msgFileThumbPadding.top(), st::msgFileThumbSize, st::msgFileThumbSize, _width));
|
||||
@ -1242,7 +1242,7 @@ void LayoutOverviewLink::paint(Painter &p, const QRect &clip, uint32 selection,
|
||||
}
|
||||
|
||||
if (clip.intersects(rtlrect(left, 0, w, st::linksBorder, _width))) {
|
||||
p.fillRect(clip.intersected(rtlrect(left, 0, w, st::linksBorder, _width)), st::linksBorderColor);
|
||||
p.fillRect(clip.intersected(rtlrect(left, 0, w, st::linksBorder, _width)), st::linksBorderFg);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1394,7 +1394,7 @@ void LayoutInlineGif::paint(Painter &p, const QRect &clip, uint32 selection, con
|
||||
|
||||
QRect r(0, 0, _width, height);
|
||||
if (animating) {
|
||||
if (!_thumb.isNull()) const_cast<LayoutInlineGif*>(this)->_thumb = QPixmap();
|
||||
if (!_thumb.isNull()) _thumb = QPixmap();
|
||||
const InlinePaintContext *ctx = context->toInlinePaintContext();
|
||||
t_assert(ctx);
|
||||
p.drawPixmap(r.topLeft(), _gif->current(frame.width(), frame.height(), _width, height, ctx->paused ? 0 : context->ms));
|
||||
@ -1532,7 +1532,7 @@ void LayoutInlineGif::prepareThumb(int32 width, int32 height, const QSize &frame
|
||||
if (_doc && !_doc->thumb->isNull()) {
|
||||
if (_doc->thumb->loaded()) {
|
||||
if (_thumb.width() != width * cIntRetinaFactor() || _thumb.height() != height * cIntRetinaFactor()) {
|
||||
const_cast<LayoutInlineGif*>(this)->_thumb = _doc->thumb->pixNoCache(frame.width() * cIntRetinaFactor(), frame.height() * cIntRetinaFactor(), true, false, false, width, height);
|
||||
_thumb = _doc->thumb->pixNoCache(frame.width() * cIntRetinaFactor(), frame.height() * cIntRetinaFactor(), true, false, false, width, height);
|
||||
}
|
||||
} else {
|
||||
_doc->thumb->load();
|
||||
@ -1540,7 +1540,7 @@ void LayoutInlineGif::prepareThumb(int32 width, int32 height, const QSize &frame
|
||||
} else if (_result && !_result->thumb_url.isEmpty()) {
|
||||
if (_result->thumb->loaded()) {
|
||||
if (_thumb.width() != width * cIntRetinaFactor() || _thumb.height() != height * cIntRetinaFactor()) {
|
||||
const_cast<LayoutInlineGif*>(this)->_thumb = _result->thumb->pixNoCache(frame.width() * cIntRetinaFactor(), frame.height() * cIntRetinaFactor(), true, false, false, width, height);
|
||||
_thumb = _result->thumb->pixNoCache(frame.width() * cIntRetinaFactor(), frame.height() * cIntRetinaFactor(), true, false, false, width, height);
|
||||
}
|
||||
} else {
|
||||
_result->thumb->load();
|
||||
@ -1804,3 +1804,233 @@ void LayoutInlinePhoto::content_forget() {
|
||||
_result->forget();
|
||||
}
|
||||
}
|
||||
|
||||
LayoutInlineWebVideo::LayoutInlineWebVideo(InlineResult *result) : LayoutInlineItem(result, 0, 0)
|
||||
, _send(new SendInlineItemLink())
|
||||
, _title(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->duration) {
|
||||
_duration = formatDurationText(_result->duration);
|
||||
}
|
||||
}
|
||||
|
||||
void LayoutInlineWebVideo::initDimensions() {
|
||||
_maxw = st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft;
|
||||
int32 textWidth = _maxw - (_result->thumb->isNull() ? 0 : (st::inlineThumbSize + st::inlineThumbSkip));
|
||||
TextParseOptions titleOpts = { 0, _maxw, 2 * st::semiboldFont->height, Qt::LayoutDirectionAuto };
|
||||
_title.setText(st::semiboldFont, textOneLine(_result->title), titleOpts);
|
||||
int32 titleHeight = qMin(_title.countHeight(_maxw), 2 * st::semiboldFont->height);
|
||||
|
||||
int32 descriptionLines = _result->thumb->isNull() ? 3 : (titleHeight > st::semiboldFont->height ? 1 : 2);
|
||||
|
||||
TextParseOptions descriptionOpts = { TextParseMultiline, _maxw, descriptionLines * st::normalFont->height, Qt::LayoutDirectionAuto };
|
||||
_description.setText(st::normalFont, _result->description, descriptionOpts);
|
||||
int32 descriptionHeight = qMin(_description.countHeight(_maxw), descriptionLines * st::normalFont->height);
|
||||
|
||||
_minh = _result->thumb->isNull() ? titleHeight + descriptionHeight : st::inlineThumbSize;
|
||||
_minh += st::inlineRowMargin * 2 + st::inlineRowBorder;
|
||||
}
|
||||
|
||||
void LayoutInlineWebVideo::paint(Painter &p, const QRect &clip, uint32 selection, const PaintContext *context) const {
|
||||
int32 left = 0;
|
||||
if (!_result->thumb->isNull()) {
|
||||
left = st::inlineThumbSize + st::inlineThumbSkip;
|
||||
prepareThumb(st::inlineThumbSize, st::inlineThumbSize);
|
||||
if (_thumb.isNull()) {
|
||||
p.fillRect(rtlrect(0, st::inlineRowMargin, st::inlineThumbSize, st::inlineThumbSize, _width), _result->thumb->isNull() ? st::black : st::overviewPhotoBg);
|
||||
} else {
|
||||
p.drawPixmapLeft(0, st::inlineRowMargin, _width, _thumb);
|
||||
}
|
||||
|
||||
if (!_duration.isEmpty()) {
|
||||
int32 durationTop = st::inlineRowMargin + st::inlineThumbSize - st::normalFont->height - st::inlineDurationMargin;
|
||||
p.fillRect(rtlrect(0, durationTop - st::inlineDurationMargin, st::inlineThumbSize, st::normalFont->height + 2 * st::inlineDurationMargin, _width), st::msgDateImgBg);
|
||||
p.setPen(st::white);
|
||||
p.setFont(st::normalFont);
|
||||
p.drawTextRight(_width - st::inlineThumbSize + st::inlineDurationMargin, durationTop, _width, _duration);
|
||||
}
|
||||
}
|
||||
|
||||
p.setPen(st::black);
|
||||
_title.drawLeftElided(p, left, st::inlineRowMargin, _width - left, _width, 2);
|
||||
int32 titleHeight = qMin(_title.countHeight(_width - left), st::semiboldFont->height * 2);
|
||||
|
||||
p.setPen(st::inlineDescriptionFg);
|
||||
int32 descriptionLines = _result->thumb->isNull() ? 3 : (titleHeight > st::semiboldFont->height ? 1 : 2);
|
||||
_description.drawLeftElided(p, left, st::inlineRowMargin + titleHeight, _width - left, _width, descriptionLines);
|
||||
|
||||
const InlinePaintContext *ctx = context->toInlinePaintContext();
|
||||
t_assert(ctx);
|
||||
if (!ctx->lastRow) {
|
||||
p.fillRect(rtlrect(left, _height - st::inlineRowBorder, _width - left, st::inlineRowBorder, _width), st::inlineRowBorderFg);
|
||||
}
|
||||
}
|
||||
|
||||
void LayoutInlineWebVideo::getState(TextLinkPtr &link, HistoryCursorState &cursor, int32 x, int32 y) const {
|
||||
if (x >= 0 && x < _width && y >= 0 && y < _height) {
|
||||
link = _send;
|
||||
}
|
||||
}
|
||||
|
||||
void LayoutInlineWebVideo::prepareThumb(int32 width, int32 height) const {
|
||||
if (_result->thumb->loaded()) {
|
||||
if (_thumb.width() != width * cIntRetinaFactor() || _thumb.height() != height * cIntRetinaFactor()) {
|
||||
int32 w = qMax(_result->thumb->width(), 1), h = qMax(_result->thumb->height(), 1);
|
||||
if (w * height > h * width) {
|
||||
if (height < h) {
|
||||
w = w * height / h;
|
||||
h = height;
|
||||
}
|
||||
} else {
|
||||
if (width < w) {
|
||||
h = h * width / w;
|
||||
w = width;
|
||||
}
|
||||
}
|
||||
_thumb = _result->thumb->pixNoCache(w * cIntRetinaFactor(), h * cIntRetinaFactor(), true, false, false, width, height);
|
||||
}
|
||||
} else {
|
||||
_result->thumb->load();
|
||||
}
|
||||
}
|
||||
|
||||
LayoutInlineArticle::LayoutInlineArticle(InlineResult *result, bool withThumb) : LayoutInlineItem(result, 0, 0)
|
||||
, _send(new SendInlineItemLink())
|
||||
, _url(result->url.isEmpty() ? 0 : linkFromUrl(result->url))
|
||||
, _withThumb(withThumb)
|
||||
, _title(st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft - st::inlineThumbSize - st::inlineThumbSkip)
|
||||
, _description(st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft - st::inlineThumbSize - st::inlineThumbSkip) {
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
void LayoutInlineArticle::initDimensions() {
|
||||
_maxw = st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft;
|
||||
int32 textWidth = _maxw - (_withThumb ? (st::inlineThumbSize + st::inlineThumbSkip) : 0);
|
||||
TextParseOptions titleOpts = { 0, _maxw, 2 * st::semiboldFont->height, Qt::LayoutDirectionAuto };
|
||||
_title.setText(st::semiboldFont, textOneLine(_result->title), titleOpts);
|
||||
int32 titleHeight = qMin(_title.countHeight(_maxw), 2 * st::semiboldFont->height);
|
||||
|
||||
int32 descriptionLines = (_withThumb || _url) ? 2 : 3;
|
||||
|
||||
TextParseOptions descriptionOpts = { TextParseMultiline, _maxw, descriptionLines * st::normalFont->height, Qt::LayoutDirectionAuto };
|
||||
_description.setText(st::normalFont, _result->description, descriptionOpts);
|
||||
int32 descriptionHeight = qMin(_description.countHeight(_maxw), descriptionLines * st::normalFont->height);
|
||||
|
||||
_minh = titleHeight + descriptionHeight;
|
||||
if (_url) _minh += st::normalFont->height;
|
||||
if (_withThumb) _minh = qMax(_minh, int32(st::inlineThumbSize));
|
||||
_minh += st::inlineRowMargin * 2 + st::inlineRowBorder;
|
||||
}
|
||||
|
||||
int32 LayoutInlineArticle::resizeGetHeight(int32 width) {
|
||||
_width = qMin(width, _maxw);
|
||||
if (_url) {
|
||||
_urlText = _result->url;
|
||||
_urlWidth = st::normalFont->width(_urlText);
|
||||
if (_urlWidth > _width - st::inlineThumbSize - st::inlineThumbSkip) {
|
||||
_urlText = st::normalFont->elided(_result->url, _width - st::inlineThumbSize - st::inlineThumbSkip);
|
||||
_urlWidth = st::normalFont->width(_urlText);
|
||||
}
|
||||
}
|
||||
_height = _minh;
|
||||
return _height;
|
||||
}
|
||||
|
||||
void LayoutInlineArticle::paint(Painter &p, const QRect &clip, uint32 selection, const PaintContext *context) const {
|
||||
int32 left = 0;
|
||||
if (_withThumb) {
|
||||
left = st::inlineThumbSize + st::inlineThumbSkip;
|
||||
prepareThumb(st::inlineThumbSize, st::inlineThumbSize);
|
||||
QRect rthumb(rtlrect(0, st::inlineRowMargin, st::inlineThumbSize, st::inlineThumbSize, _width));
|
||||
if (_thumb.isNull()) {
|
||||
if (_result->thumb->isNull() && !_letter.isEmpty()) {
|
||||
int32 index = (_letter.at(0).unicode() % 4);
|
||||
style::color colors[] = { st::msgFileRedColor, st::msgFileYellowColor, st::msgFileGreenColor, st::msgFileBlueColor };
|
||||
|
||||
p.fillRect(rthumb, colors[index]);
|
||||
if (!_letter.isEmpty()) {
|
||||
p.setFont(st::linksLetterFont);
|
||||
p.setPen(st::white);
|
||||
p.drawText(rthumb, _letter, style::al_center);
|
||||
}
|
||||
} else {
|
||||
p.fillRect(rthumb, st::overviewPhotoBg);
|
||||
}
|
||||
} else {
|
||||
p.drawPixmapLeft(rthumb.topLeft(), _width, _thumb);
|
||||
}
|
||||
}
|
||||
|
||||
p.setPen(st::black);
|
||||
_title.drawLeftElided(p, left, st::inlineRowMargin, _width - left, _width, 2);
|
||||
int32 titleHeight = qMin(_title.countHeight(_width - left), st::semiboldFont->height * 2);
|
||||
|
||||
p.setPen(st::inlineDescriptionFg);
|
||||
int32 descriptionLines = (_withThumb || _url) ? 2 : 3;
|
||||
_description.drawLeftElided(p, left, st::inlineRowMargin + titleHeight, _width - left, _width, descriptionLines);
|
||||
|
||||
if (_url) {
|
||||
int32 descriptionHeight = qMin(_description.countHeight(_width - left), st::normalFont->height * descriptionLines);
|
||||
p.drawTextLeft(left, st::inlineRowMargin + titleHeight + descriptionHeight, _width, _urlText, _urlWidth);
|
||||
}
|
||||
|
||||
const InlinePaintContext *ctx = context->toInlinePaintContext();
|
||||
t_assert(ctx);
|
||||
if (!ctx->lastRow) {
|
||||
p.fillRect(rtlrect(left, _height - st::inlineRowBorder, _width - left, st::inlineRowBorder, _width), st::inlineRowBorderFg);
|
||||
}
|
||||
}
|
||||
|
||||
void LayoutInlineArticle::getState(TextLinkPtr &link, HistoryCursorState &cursor, int32 x, int32 y) const {
|
||||
if (x >= 0 && x < _width && y >= 0 && y < _height) {
|
||||
if (_url) {
|
||||
int32 left = st::inlineThumbSize + st::inlineThumbSkip;
|
||||
int32 titleHeight = qMin(_title.countHeight(_width - left), st::semiboldFont->height * 2);
|
||||
int32 descriptionLines = 2;
|
||||
int32 descriptionHeight = qMin(_description.countHeight(_width - left), st::normalFont->height * descriptionLines);
|
||||
if (rtlrect(left, st::inlineRowMargin + titleHeight + descriptionHeight, _urlWidth, st::normalFont->height, _width).contains(x, y)) {
|
||||
link = _url;
|
||||
return;
|
||||
}
|
||||
}
|
||||
link = _send;
|
||||
}
|
||||
}
|
||||
|
||||
void LayoutInlineArticle::prepareThumb(int32 width, int32 height) const {
|
||||
if (_result->thumb->isNull()) return;
|
||||
|
||||
if (_result->thumb->loaded()) {
|
||||
if (_thumb.width() != width * cIntRetinaFactor() || _thumb.height() != height * cIntRetinaFactor()) {
|
||||
int32 w = qMax(_result->thumb->width(), 1), h = qMax(_result->thumb->height(), 1);
|
||||
if (w * height > h * width) {
|
||||
if (height < h) {
|
||||
w = w * height / h;
|
||||
h = height;
|
||||
}
|
||||
} else {
|
||||
if (width < w) {
|
||||
h = h * width / w;
|
||||
w = width;
|
||||
}
|
||||
}
|
||||
_thumb = _result->thumb->pixNoCache(w * cIntRetinaFactor(), h * cIntRetinaFactor(), true, false, false, width, height);
|
||||
}
|
||||
} else {
|
||||
_result->thumb->load();
|
||||
}
|
||||
}
|
||||
|
@ -477,12 +477,15 @@ private:
|
||||
|
||||
class InlinePaintContext : public PaintContext {
|
||||
public:
|
||||
InlinePaintContext(uint64 ms, bool selecting, bool paused) : PaintContext(ms, selecting), paused(paused) {
|
||||
InlinePaintContext(uint64 ms, bool selecting, bool paused, bool lastRow)
|
||||
: PaintContext(ms, selecting)
|
||||
, paused(paused)
|
||||
, lastRow(lastRow) {
|
||||
}
|
||||
virtual const InlinePaintContext *toInlinePaintContext() const {
|
||||
return this;
|
||||
}
|
||||
bool paused;
|
||||
bool paused, lastRow;
|
||||
};
|
||||
|
||||
class LayoutInlineItem : public LayoutItem {
|
||||
@ -629,3 +632,49 @@ private:
|
||||
void prepareThumb(int32 width, int32 height, const QSize &frame) const;
|
||||
|
||||
};
|
||||
|
||||
class LayoutInlineWebVideo : public LayoutInlineItem {
|
||||
public:
|
||||
LayoutInlineWebVideo(InlineResult *result);
|
||||
|
||||
virtual void initDimensions();
|
||||
|
||||
virtual void paint(Painter &p, const QRect &clip, uint32 selection, const PaintContext *context) const;
|
||||
virtual void getState(TextLinkPtr &link, HistoryCursorState &cursor, int32 x, int32 y) const;
|
||||
|
||||
private:
|
||||
|
||||
TextLinkPtr _send;
|
||||
|
||||
mutable QPixmap _thumb;
|
||||
Text _title, _description;
|
||||
QString _duration;
|
||||
int32 _durationWidth;
|
||||
|
||||
void prepareThumb(int32 width, int32 height) const;
|
||||
|
||||
};
|
||||
|
||||
class LayoutInlineArticle : public LayoutInlineItem {
|
||||
public:
|
||||
LayoutInlineArticle(InlineResult *result, bool withThumb);
|
||||
|
||||
virtual void initDimensions();
|
||||
virtual int32 resizeGetHeight(int32 width);
|
||||
|
||||
virtual void paint(Painter &p, const QRect &clip, uint32 selection, const PaintContext *context) const;
|
||||
virtual void getState(TextLinkPtr &link, HistoryCursorState &cursor, int32 x, int32 y) const;
|
||||
|
||||
private:
|
||||
|
||||
TextLinkPtr _send, _url;
|
||||
|
||||
bool _withThumb;
|
||||
mutable QPixmap _thumb;
|
||||
Text _title, _description;
|
||||
QString _letter, _urlText;
|
||||
int32 _urlWidth;
|
||||
|
||||
void prepareThumb(int32 width, int32 height) const;
|
||||
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user