mirror of https://github.com/procxx/kepka.git
caching web files to local, sending of inline bots results done properly, panel ux better for inline bots
This commit is contained in:
parent
945d9b1883
commit
35d4754380
|
@ -554,8 +554,8 @@ taDefFlat: flatTextarea {
|
|||
font: inpDefFont;
|
||||
cursor: cursor(text);
|
||||
|
||||
phColor: #AAA;
|
||||
phFocusColor: #CCC;
|
||||
phColor: #999;
|
||||
phFocusColor: #AAA;
|
||||
phAlign: align(topleft);
|
||||
phPos: point(2px, 0px);
|
||||
phShift: 50px;
|
||||
|
|
|
@ -1443,6 +1443,18 @@ namespace App {
|
|||
return 0;
|
||||
}
|
||||
|
||||
void updateImage(ImagePtr &old, ImagePtr now) {
|
||||
if (now->isNull()) return;
|
||||
if (old->isNull()) {
|
||||
old = now;
|
||||
} else if (DelayedStorageImage *img = old->toDelayedStorageImage()) {
|
||||
StorageImageLocation loc = now->location();
|
||||
if (!loc.isNull()) {
|
||||
img->setStorageLocation(loc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PhotoData *photo(const PhotoId &photo) {
|
||||
PhotosData::const_iterator i = ::photosData.constFind(photo);
|
||||
if (i == ::photosData.cend()) {
|
||||
|
@ -1465,9 +1477,9 @@ namespace App {
|
|||
if (date) {
|
||||
convert->access = access;
|
||||
convert->date = date;
|
||||
if (convert->thumb->isNull() && !thumb->isNull()) convert->thumb = thumb;
|
||||
if (convert->medium->isNull() && !medium->isNull()) convert->medium = medium;
|
||||
if (convert->full->isNull() && !full->isNull()) convert->full = full;
|
||||
updateImage(convert->thumb, thumb);
|
||||
updateImage(convert->medium, medium);
|
||||
updateImage(convert->full, full);
|
||||
}
|
||||
}
|
||||
PhotosData::const_iterator i = ::photosData.constFind(photo);
|
||||
|
@ -1485,9 +1497,9 @@ namespace App {
|
|||
if (result != convert && date) {
|
||||
result->access = access;
|
||||
result->date = date;
|
||||
if (result->thumb->isNull() && !thumb->isNull()) result->thumb = thumb;
|
||||
if (result->medium->isNull() && !medium->isNull()) result->medium = medium;
|
||||
if (result->full->isNull() && !full->isNull()) result->full = full;
|
||||
updateImage(result->thumb, thumb);
|
||||
updateImage(result->medium, medium);
|
||||
updateImage(result->full, full);
|
||||
}
|
||||
inLastIter = lastPhotosMap.find(result);
|
||||
}
|
||||
|
@ -1526,9 +1538,7 @@ namespace App {
|
|||
if (date) {
|
||||
convert->access = access;
|
||||
convert->date = date;
|
||||
if (convert->thumb->isNull() && !thumb->isNull()) {
|
||||
convert->thumb = thumb;
|
||||
}
|
||||
updateImage(convert->thumb, thumb);
|
||||
convert->duration = duration;
|
||||
convert->w = w;
|
||||
convert->h = h;
|
||||
|
@ -1553,9 +1563,7 @@ namespace App {
|
|||
result->duration = duration;
|
||||
result->w = w;
|
||||
result->h = h;
|
||||
if (result->thumb->isNull() && !thumb->isNull()) {
|
||||
result->thumb = thumb;
|
||||
}
|
||||
updateImage(result->thumb, thumb);
|
||||
result->dc = dc;
|
||||
result->size = size;
|
||||
}
|
||||
|
@ -1632,9 +1640,6 @@ namespace App {
|
|||
Local::copyStickerImage(mediaKey(DocumentFileLocation, convert->dc, convert->id), mediaKey(DocumentFileLocation, dc, document));
|
||||
convert->id = document;
|
||||
convert->status = FileReady;
|
||||
if (cSavedGifs().indexOf(convert) >= 0) { // id changed
|
||||
Local::writeSavedGifs();
|
||||
}
|
||||
sentSticker = !!convert->sticker();
|
||||
}
|
||||
if (date) {
|
||||
|
@ -1652,6 +1657,11 @@ namespace App {
|
|||
convert->sticker()->loc = thumbLocation;
|
||||
}
|
||||
}
|
||||
|
||||
if (cSavedGifs().indexOf(convert) >= 0) { // id changed
|
||||
Local::writeSavedGifs();
|
||||
}
|
||||
|
||||
const FileLocation &loc(convert->location(true));
|
||||
if (!loc.isEmpty()) {
|
||||
Local::writeFileLocation(mediaKey(DocumentFileLocation, convert->dc, convert->id), loc);
|
||||
|
|
|
@ -330,6 +330,7 @@ void AutoDownloadBox::onSave() {
|
|||
for (DocumentsData::const_iterator i = data.cbegin(), e = data.cend(); i != e; ++i) {
|
||||
i.value()->automaticLoadSettingsChanged();
|
||||
}
|
||||
Notify::automaticLoadSettingsChangedGif();
|
||||
}
|
||||
changed = true;
|
||||
}
|
||||
|
|
|
@ -1252,7 +1252,7 @@ void StickerPanInner::setScrollTop(int top) {
|
|||
}
|
||||
|
||||
int StickerPanInner::countHeight() {
|
||||
int result = 0, minLastH = _maxHeight - st::rbEmoji.height - st::stickerPanPadding;
|
||||
int result = 0, minLastH = _maxHeight - st::stickerPanPadding;
|
||||
if (_showingInlineItems) {
|
||||
result = st::emojiPanHeader;
|
||||
for (int i = 0, l = _inlineRows.count(); i < l; ++i) {
|
||||
|
@ -1560,6 +1560,10 @@ void StickerPanInner::enterFromChildEvent(QEvent *e) {
|
|||
updateSelected();
|
||||
}
|
||||
|
||||
bool StickerPanInner::showSectionIcons() const {
|
||||
return !inlineResultsShown();
|
||||
}
|
||||
|
||||
void StickerPanInner::clearSelection(bool fast) {
|
||||
_lastMousePos = mapToGlobal(QPoint(-10, -10));
|
||||
if (fast) {
|
||||
|
@ -2347,6 +2351,7 @@ void StickerPanInner::showStickerSet(uint64 setId) {
|
|||
refreshSavedGifs();
|
||||
emit scrollToY(0);
|
||||
emit scrollUpdated();
|
||||
_setGifCommand = App::insertBotCommand(qsl("@gif"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2447,9 +2452,28 @@ EmojiSwitchButton::EmojiSwitchButton(QWidget *parent, bool toStickers) : Button(
|
|||
updateText();
|
||||
}
|
||||
|
||||
void EmojiSwitchButton::updateText() {
|
||||
_text = lang(_toStickers ? (cSavedGifs().isEmpty() ? lng_switch_stickers : lng_switch_stickers_gifs) : lng_switch_emoji);
|
||||
void EmojiSwitchButton::updateText(const QString &inlineBotUsername) {
|
||||
if (_toStickers) {
|
||||
if (inlineBotUsername.isEmpty()) {
|
||||
_text = lang(cSavedGifs().isEmpty() ? lng_switch_stickers : lng_switch_stickers_gifs);
|
||||
} else {
|
||||
_text = '@' + inlineBotUsername;
|
||||
}
|
||||
} else {
|
||||
_text = lang(lng_switch_emoji);
|
||||
}
|
||||
_textWidth = st::emojiPanHeaderFont->width(_text);
|
||||
if (_toStickers && !inlineBotUsername.isEmpty()) {
|
||||
int32 maxw = 0;
|
||||
for (int c = 0; c < emojiTabCount; ++c) {
|
||||
maxw = qMax(maxw, st::emojiPanHeaderFont->width(lang(LangKey(lng_emoji_category0 + c))));
|
||||
}
|
||||
maxw += st::emojiPanHeaderLeft + st::emojiSwitchSkip + (st::emojiSwitchSkip - st::emojiSwitchImgSkip);
|
||||
if (_textWidth > st::emojiPanWidth - maxw) {
|
||||
_text = st::emojiPanHeaderFont->elided(_text, st::emojiPanWidth - maxw);
|
||||
_textWidth = st::emojiPanHeaderFont->width(_text);
|
||||
}
|
||||
}
|
||||
|
||||
int32 w = st::emojiSwitchSkip + _textWidth + (st::emojiSwitchSkip - st::emojiSwitchImgSkip);
|
||||
resize(w, st::emojiPanHeader);
|
||||
|
@ -2471,6 +2495,8 @@ void EmojiSwitchButton::paintEvent(QPaintEvent *e) {
|
|||
|
||||
EmojiPan::EmojiPan(QWidget *parent) : TWidget(parent)
|
||||
, _maxHeight(st::emojiPanMaxHeight)
|
||||
, _maxHeightEmoji(_maxHeight - st::rbEmoji.height)
|
||||
, _maxHeightStickers(_maxHeight - st::rbEmoji.height)
|
||||
, _horizontal(false)
|
||||
, _noTabUpdate(false)
|
||||
, _hiding(false)
|
||||
|
@ -2518,8 +2544,8 @@ EmojiPan::EmojiPan(QWidget *parent) : TWidget(parent)
|
|||
_height = st::dropdownDef.padding.top() + _maxHeight + st::dropdownDef.padding.bottom();
|
||||
resize(_width, _height);
|
||||
|
||||
e_scroll.resize(st::emojiPanWidth, _maxHeight - st::rbEmoji.height);
|
||||
s_scroll.resize(st::emojiPanWidth, _maxHeight - st::rbEmoji.height);
|
||||
e_scroll.resize(st::emojiPanWidth, _maxHeightEmoji);
|
||||
s_scroll.resize(st::emojiPanWidth, _maxHeightStickers);
|
||||
|
||||
e_scroll.move(st::dropdownDef.padding.left(), st::dropdownDef.padding.top());
|
||||
e_scroll.setWidget(&e_inner);
|
||||
|
@ -2588,24 +2614,28 @@ EmojiPan::EmojiPan(QWidget *parent) : TWidget(parent)
|
|||
|
||||
void EmojiPan::setMaxHeight(int32 h) {
|
||||
h = qMin(int(st::emojiPanMaxHeight), h);
|
||||
if (h == _maxHeight) return;
|
||||
int32 he = h - st::rbEmoji.height;
|
||||
int32 hs = h - (s_inner.showSectionIcons() ? st::rbEmoji.height : 0);
|
||||
if (h == _maxHeight && he == _maxHeightEmoji && hs == _maxHeightStickers) return;
|
||||
|
||||
int32 was = _maxHeight;
|
||||
int32 was = _maxHeight, wase = _maxHeightEmoji, wass = _maxHeightStickers;
|
||||
_maxHeight = h;
|
||||
_maxHeightEmoji = he;
|
||||
_maxHeightStickers = hs;
|
||||
|
||||
_height = st::dropdownDef.padding.top() + _maxHeight + st::dropdownDef.padding.bottom();
|
||||
resize(_width, _height);
|
||||
|
||||
if (was > _maxHeight) {
|
||||
e_scroll.resize(st::emojiPanWidth, _maxHeight - st::rbEmoji.height);
|
||||
s_scroll.resize(st::emojiPanWidth, _maxHeight - st::rbEmoji.height);
|
||||
s_inner.setMaxHeight(_maxHeight);
|
||||
e_inner.setMaxHeight(_maxHeight);
|
||||
if (was > _maxHeight || (was == _maxHeight && wass > _maxHeightStickers)) {
|
||||
e_scroll.resize(st::emojiPanWidth, _maxHeightEmoji);
|
||||
s_scroll.resize(st::emojiPanWidth, _maxHeightStickers);
|
||||
s_inner.setMaxHeight(_maxHeightStickers);
|
||||
e_inner.setMaxHeight(_maxHeightEmoji);
|
||||
} else {
|
||||
s_inner.setMaxHeight(_maxHeight);
|
||||
e_inner.setMaxHeight(_maxHeight);
|
||||
e_scroll.resize(st::emojiPanWidth, _maxHeight - st::rbEmoji.height);
|
||||
s_scroll.resize(st::emojiPanWidth, _maxHeight - st::rbEmoji.height);
|
||||
s_inner.setMaxHeight(_maxHeightStickers);
|
||||
e_inner.setMaxHeight(_maxHeightEmoji);
|
||||
e_scroll.resize(st::emojiPanWidth, _maxHeightEmoji);
|
||||
s_scroll.resize(st::emojiPanWidth, _maxHeightStickers);
|
||||
}
|
||||
|
||||
_iconsTop = st::dropdownDef.padding.top() + _maxHeight - st::rbEmoji.height;
|
||||
|
@ -2657,7 +2687,7 @@ void EmojiPan::paintEvent(QPaintEvent *e) {
|
|||
if (_toCache.isNull()) {
|
||||
if (_cache.isNull()) {
|
||||
p.fillRect(myrtlrect(r.x() + r.width() - st::emojiScroll.width, r.y(), st::emojiScroll.width, e_scroll.height()), st::white->b);
|
||||
if (_stickersShown) {
|
||||
if (_stickersShown && s_inner.showSectionIcons()) {
|
||||
p.fillRect(r.left(), _iconsTop, r.width(), st::rbEmoji.height, st::emojiPanCategories->b);
|
||||
p.drawSpriteLeft(_iconsLeft + 7 * st::rbEmoji.width + st::rbEmojiRecent.imagePos.x(), _iconsTop + st::rbEmojiRecent.imagePos.y(), width(), st::stickersSettings);
|
||||
|
||||
|
@ -2748,6 +2778,18 @@ void EmojiPan::paintEvent(QPaintEvent *e) {
|
|||
}
|
||||
}
|
||||
|
||||
void EmojiPan::moveBottom(int32 bottom, bool force) {
|
||||
if (isHidden() && !force) {
|
||||
move(x(), bottom - height());
|
||||
return;
|
||||
}
|
||||
if (_stickersShown && s_inner.inlineResultsShown()) {
|
||||
moveToLeft(0, bottom - height());
|
||||
} else {
|
||||
moveToRight(0, bottom - height());
|
||||
}
|
||||
}
|
||||
|
||||
void EmojiPan::enterEvent(QEvent *e) {
|
||||
_hideTimer.stop();
|
||||
if (_hiding) showStart();
|
||||
|
@ -2919,7 +2961,10 @@ void EmojiPan::onRefreshIcons() {
|
|||
}
|
||||
updatePanelsPositions(s_panels, s_scroll.scrollTop());
|
||||
updateSelected();
|
||||
if (_stickersShown) validateSelectedIcon();
|
||||
if (_stickersShown) {
|
||||
validateSelectedIcon();
|
||||
setMaxHeight(_maxHeight);
|
||||
}
|
||||
updateIcons();
|
||||
}
|
||||
|
||||
|
@ -2995,6 +3040,8 @@ void EmojiPan::updateSelected() {
|
|||
}
|
||||
|
||||
void EmojiPan::updateIcons() {
|
||||
if (!_stickersShown || !s_inner.showSectionIcons()) return;
|
||||
|
||||
QRect r(st::dropdownDef.padding.left(), st::dropdownDef.padding.top(), _width - st::dropdownDef.padding.left() - st::dropdownDef.padding.right(), _height - st::dropdownDef.padding.top() - st::dropdownDef.padding.bottom());
|
||||
update(r.left(), _iconsTop, r.width(), st::rbEmoji.height);
|
||||
}
|
||||
|
@ -3108,6 +3155,7 @@ void EmojiPan::hideFinish() {
|
|||
_cache = _toCache = _fromCache = QPixmap();
|
||||
_a_slide.stop();
|
||||
_horizontal = false;
|
||||
_hiding = false;
|
||||
|
||||
e_scroll.scrollToY(0);
|
||||
if (!_recent.checked()) {
|
||||
|
@ -3129,16 +3177,26 @@ void EmojiPan::hideFinish() {
|
|||
}
|
||||
|
||||
void EmojiPan::showStart() {
|
||||
if (!isHidden() && a_opacity.current() == 1) {
|
||||
if (!isHidden() && !_hiding) {
|
||||
return;
|
||||
}
|
||||
if (isHidden()) {
|
||||
e_inner.refreshRecent();
|
||||
if (s_inner.inlineResultsShown() && refreshInlineRows()) {
|
||||
_stickersShown = true;
|
||||
} else {
|
||||
s_inner.refreshRecent();
|
||||
s_inner.preloadImages();
|
||||
_stickersShown = false;
|
||||
}
|
||||
s_inner.preloadImages();
|
||||
setMaxHeight(_maxHeight);
|
||||
_fromCache = _toCache = QPixmap();
|
||||
_a_slide.stop();
|
||||
moveBottom(y() + height(), true);
|
||||
} else if (_hiding) {
|
||||
if (s_inner.inlineResultsShown() && refreshInlineRows()) {
|
||||
onSwitch();
|
||||
}
|
||||
}
|
||||
if (_cache.isNull()) {
|
||||
QPixmap from = _fromCache, to = _toCache;
|
||||
|
@ -3170,9 +3228,10 @@ bool EmojiPan::eventFilter(QObject *obj, QEvent *e) {
|
|||
//}
|
||||
} else if (e->type() == QEvent::MouseButtonPress && static_cast<QMouseEvent*>(e)->button() == Qt::LeftButton/* && !dynamic_cast<StickerPan*>(obj)*/) {
|
||||
if (isHidden() || _hiding) {
|
||||
otherEnter();
|
||||
_hideTimer.stop();
|
||||
showStart();
|
||||
} else {
|
||||
otherLeave();
|
||||
hideAnimated();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
@ -3181,6 +3240,7 @@ bool EmojiPan::eventFilter(QObject *obj, QEvent *e) {
|
|||
void EmojiPan::stickersInstalled(uint64 setId) {
|
||||
_stickersShown = true;
|
||||
if (isHidden()) {
|
||||
moveBottom(y() + height(), true);
|
||||
show();
|
||||
a_opacity = anim::fvalue(0, 1);
|
||||
a_opacity.update(0, anim::linear);
|
||||
|
@ -3188,6 +3248,7 @@ void EmojiPan::stickersInstalled(uint64 setId) {
|
|||
}
|
||||
showAll();
|
||||
s_inner.showStickerSet(setId);
|
||||
setMaxHeight(_maxHeight);
|
||||
showStart();
|
||||
}
|
||||
|
||||
|
@ -3211,6 +3272,14 @@ bool EmojiPan::ui_isInlineItemBeingChosen() {
|
|||
return false;
|
||||
}
|
||||
|
||||
void EmojiPan::notify_automaticLoadSettingsChangedGif() {
|
||||
for (InlineCache::const_iterator i = _inlineCache.cbegin(), ei = _inlineCache.cend(); i != ei; ++i) {
|
||||
for (InlineResults::const_iterator j = i.value()->results.cbegin(), ej = i.value()->results.cend(); j != ej; ++j) {
|
||||
(*j)->automaticLoadSettingsChangedGif();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EmojiPan::showAll() {
|
||||
if (_stickersShown) {
|
||||
s_scroll.show();
|
||||
|
@ -3344,20 +3413,20 @@ void EmojiPan::onSwitch() {
|
|||
_stickersShown = !_stickersShown;
|
||||
if (!_stickersShown) {
|
||||
Notify::clipStopperHidden(ClipStopperSavedGifsPanel);
|
||||
}
|
||||
|
||||
} else {
|
||||
if (cShowingSavedGifs() && cSavedGifs().isEmpty()) {
|
||||
s_inner.showStickerSet(DefaultStickerSetId);
|
||||
} else if (!cShowingSavedGifs() && !cSavedGifs().isEmpty() && cStickerSets().isEmpty()) {
|
||||
s_inner.showStickerSet(NoneStickerSetId);
|
||||
}
|
||||
validateSelectedIcon();
|
||||
setMaxHeight(_maxHeight);
|
||||
}
|
||||
_iconOver = -1;
|
||||
_iconHovers = _icons.isEmpty() ? QVector<float64>() : QVector<float64>(_icons.size(), 0);
|
||||
_iconAnimations.clear();
|
||||
_a_icons.stop();
|
||||
|
||||
validateSelectedIcon();
|
||||
|
||||
_cache = QPixmap();
|
||||
showAll();
|
||||
_toCache = myGrab(this, rect().marginsRemoved(st::dropdownDef.padding));
|
||||
|
@ -3425,10 +3494,20 @@ void EmojiPan::onDelayedHide() {
|
|||
_removingSetId = 0;
|
||||
}
|
||||
|
||||
void EmojiPan::clearInlineBot() {
|
||||
inlineBotChanged();
|
||||
e_switch.updateText();
|
||||
e_switch.moveToRight(0, 0, st::emojiPanWidth);
|
||||
}
|
||||
|
||||
void EmojiPan::inlineBotChanged() {
|
||||
if (!_inlineBot) return;
|
||||
|
||||
if (!isHidden()) hideAnimated();
|
||||
if (!isHidden() && !_hiding) {
|
||||
if (_stickersShown || !rect().contains(mapFromGlobal(QCursor::pos()))) {
|
||||
hideAnimated();
|
||||
}
|
||||
}
|
||||
|
||||
if (_inlineRequestId) MTP::cancel(_inlineRequestId);
|
||||
_inlineRequestId = 0;
|
||||
|
@ -3555,6 +3634,7 @@ void EmojiPan::queryInlineBot(UserData *bot, QString query) {
|
|||
_inlineRequestId = 0;
|
||||
}
|
||||
if (_inlineCache.contains(query)) {
|
||||
_inlineRequestTimer.stop();
|
||||
_inlineQuery = query;
|
||||
showInlineRows(true);
|
||||
} else {
|
||||
|
@ -3565,7 +3645,7 @@ void EmojiPan::queryInlineBot(UserData *bot, QString query) {
|
|||
}
|
||||
|
||||
void EmojiPan::onInlineRequest() {
|
||||
if (_inlineRequestId) return;
|
||||
if (_inlineRequestId || !_inlineBot) return;
|
||||
_inlineQuery = _inlineNextQuery;
|
||||
|
||||
QString nextOffset;
|
||||
|
@ -3577,7 +3657,7 @@ void EmojiPan::onInlineRequest() {
|
|||
_inlineRequestId = MTP::send(MTPmessages_GetInlineBotResults(_inlineBot->inputUser, MTP_string(_inlineQuery), MTP_string(nextOffset)), rpcDone(&EmojiPan::inlineResultsDone), rpcFail(&EmojiPan::inlineResultsFail));
|
||||
}
|
||||
|
||||
void EmojiPan::showInlineRows(bool newResults) {
|
||||
bool EmojiPan::refreshInlineRows() {
|
||||
bool clear = true;
|
||||
InlineCache::const_iterator i = _inlineCache.constFind(_inlineQuery);
|
||||
if (i != _inlineCache.cend()) {
|
||||
|
@ -3586,26 +3666,25 @@ void EmojiPan::showInlineRows(bool newResults) {
|
|||
}
|
||||
|
||||
s_inner.refreshInlineRows(_inlineBot, clear ? InlineResults() : i.value()->results, false);
|
||||
return !clear;
|
||||
}
|
||||
|
||||
void EmojiPan::showInlineRows(bool newResults) {
|
||||
bool clear = !refreshInlineRows();
|
||||
if (newResults) s_scroll.scrollToY(0);
|
||||
if (clear && !isHidden() && _stickersShown && s_inner.inlineResultsShown()) {
|
||||
|
||||
e_switch.updateText(clear ? QString() : _inlineBot->username);
|
||||
e_switch.moveToRight(0, 0, st::emojiPanWidth);
|
||||
|
||||
bool hidden = isHidden();
|
||||
if (clear && !hidden && _stickersShown && s_inner.inlineResultsShown()) {
|
||||
hideAnimated();
|
||||
} else if (!clear) {
|
||||
_hideTimer.stop();
|
||||
if (!isHidden() || _hiding) {
|
||||
if (!_stickersShown) {
|
||||
onSwitch();
|
||||
}
|
||||
} else {
|
||||
_stickersShown = true;
|
||||
if (isHidden()) {
|
||||
show();
|
||||
a_opacity = anim::fvalue(0, 1);
|
||||
a_opacity.update(0, anim::linear);
|
||||
_cache = _fromCache = _toCache = QPixmap();
|
||||
}
|
||||
}
|
||||
if (isHidden() || _hiding) {
|
||||
if (hidden || _hiding) {
|
||||
showStart();
|
||||
} else if (!_stickersShown) {
|
||||
onSwitch();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -336,6 +336,7 @@ public:
|
|||
void hideFinish();
|
||||
void showStickerSet(uint64 setId);
|
||||
|
||||
bool showSectionIcons() const;
|
||||
void clearSelection(bool fast = false);
|
||||
|
||||
void refreshStickers();
|
||||
|
@ -514,7 +515,7 @@ public:
|
|||
|
||||
EmojiSwitchButton(QWidget *parent, bool toStickers); // otherwise toEmoji
|
||||
void paintEvent(QPaintEvent *e);
|
||||
void updateText();
|
||||
void updateText(const QString &inlineBotUsername = QString());
|
||||
|
||||
protected:
|
||||
|
||||
|
@ -534,6 +535,8 @@ public:
|
|||
void setMaxHeight(int32 h);
|
||||
void paintEvent(QPaintEvent *e);
|
||||
|
||||
void moveBottom(int32 bottom, bool force = false);
|
||||
|
||||
void enterEvent(QEvent *e);
|
||||
void leaveEvent(QEvent *e);
|
||||
void otherEnter();
|
||||
|
@ -558,7 +561,7 @@ public:
|
|||
void stickersInstalled(uint64 setId);
|
||||
|
||||
void queryInlineBot(UserData *bot, QString query);
|
||||
void inlineBotChanged();
|
||||
void clearInlineBot();
|
||||
|
||||
bool overlaps(const QRect &globalRect) {
|
||||
if (isHidden() || !_cache.isNull()) return false;
|
||||
|
@ -574,6 +577,8 @@ public:
|
|||
bool ui_isInlineItemVisible(const LayoutInlineItem *layout);
|
||||
bool ui_isInlineItemBeingChosen();
|
||||
|
||||
void notify_automaticLoadSettingsChangedGif();
|
||||
|
||||
public slots:
|
||||
|
||||
void refreshStickers();
|
||||
|
@ -614,7 +619,7 @@ private:
|
|||
|
||||
void validateSelectedIcon(bool animated = false);
|
||||
|
||||
int32 _maxHeight;
|
||||
int32 _maxHeight, _maxHeightEmoji, _maxHeightStickers;
|
||||
bool _horizontal;
|
||||
|
||||
void leaveToChildEvent(QEvent *e);
|
||||
|
@ -693,7 +698,9 @@ private:
|
|||
InlineCache _inlineCache;
|
||||
QTimer _inlineRequestTimer;
|
||||
|
||||
void inlineBotChanged();
|
||||
void showInlineRows(bool newResults);
|
||||
bool refreshInlineRows();
|
||||
UserData *_inlineBot;
|
||||
QString _inlineQuery, _inlineNextQuery, _inlineNextOffset;
|
||||
mtpRequestId _inlineRequestId;
|
||||
|
|
|
@ -164,4 +164,8 @@ namespace Notify {
|
|||
if (MainWidget *m = App::main()) m->notify_historyItemLayoutChanged(item);
|
||||
}
|
||||
|
||||
void automaticLoadSettingsChangedGif() {
|
||||
if (MainWidget *m = App::main()) m->notify_automaticLoadSettingsChangedGif();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -90,4 +90,6 @@ namespace Notify {
|
|||
}
|
||||
void historyItemLayoutChanged(const HistoryItem *item);
|
||||
|
||||
void automaticLoadSettingsChangedGif();
|
||||
|
||||
};
|
||||
|
|
|
@ -30,6 +30,7 @@ FlatTextarea::FlatTextarea(QWidget *parent, const style::flatTextarea &st, const
|
|||
, _maxLength(-1)
|
||||
, _ctrlEnterSubmit(true)
|
||||
, _oldtext(v)
|
||||
, _phAfter(0)
|
||||
, _phVisible(!v.length())
|
||||
, a_phLeft(_phVisible ? 0 : st.phShift)
|
||||
, a_phAlpha(_phVisible ? 1 : 0)
|
||||
|
@ -87,8 +88,21 @@ FlatTextarea::FlatTextarea(QWidget *parent, const style::flatTextarea &st, const
|
|||
}
|
||||
}
|
||||
|
||||
void FlatTextarea::setTextFast(const QString &text) {
|
||||
void FlatTextarea::setTextFast(const QString &text, bool withUndo) {
|
||||
if (withUndo) {
|
||||
QTextCursor c(document()->docHandle(), 0);
|
||||
c.joinPreviousEditBlock();
|
||||
c.movePosition(QTextCursor::End, QTextCursor::KeepAnchor);
|
||||
c.insertText(text);
|
||||
c.movePosition(QTextCursor::End);
|
||||
c.endEditBlock();
|
||||
} else {
|
||||
setPlainText(text);
|
||||
}
|
||||
finishPlaceholder();
|
||||
}
|
||||
|
||||
void FlatTextarea::finishPlaceholder() {
|
||||
if (_a_appearance.animating()) {
|
||||
a_phLeft.finish();
|
||||
a_phAlpha.finish();
|
||||
|
@ -206,10 +220,14 @@ void FlatTextarea::paintEvent(QPaintEvent *e) {
|
|||
if (phDraw) {
|
||||
p.save();
|
||||
p.setClipRect(r);
|
||||
QRect phRect(_st.textMrg.left() - _fakeMargin + _st.phPos.x() + a_phLeft.current(), _st.textMrg.top() - _fakeMargin + _st.phPos.y(), width() - _st.textMrg.left() - _st.textMrg.right(), height() - _st.textMrg.top() - _st.textMrg.bottom());
|
||||
p.setFont(_st.font->f);
|
||||
p.setFont(_st.font);
|
||||
p.setPen(a_phColor.current());
|
||||
if (_st.phAlign == style::al_topleft && _phAfter > 0) {
|
||||
p.drawText(_st.textMrg.left() - _fakeMargin + a_phLeft.current() + _st.font->width(getLastText().mid(0, _phAfter)), _st.textMrg.top() - _fakeMargin - st::lineWidth + _st.font->ascent, _ph);
|
||||
} else {
|
||||
QRect phRect(_st.textMrg.left() - _fakeMargin + _st.phPos.x() + a_phLeft.current(), _st.textMrg.top() - _fakeMargin + _st.phPos.y(), width() - _st.textMrg.left() - _st.textMrg.right(), height() - _st.textMrg.top() - _st.textMrg.bottom());
|
||||
p.drawText(phRect, _ph, QTextOption(_st.phAlign));
|
||||
}
|
||||
p.restore();
|
||||
p.setOpacity(1);
|
||||
}
|
||||
|
@ -253,9 +271,6 @@ EmojiPtr FlatTextarea::getSingleEmoji() const {
|
|||
}
|
||||
|
||||
void FlatTextarea::getMentionHashtagBotCommandStart(QString &start, UserData *&inlineBot, QString &inlineBotUsername) const {
|
||||
int32 pos = textCursor().position();
|
||||
if (textCursor().anchor() != pos) return;
|
||||
|
||||
// check inline bot query
|
||||
const QString &text(getLastText());
|
||||
int32 inlineUsernameStart = 1, inlineUsernameLength = 0, size = text.size();
|
||||
|
@ -303,6 +318,9 @@ void FlatTextarea::getMentionHashtagBotCommandStart(QString &start, UserData *&i
|
|||
inlineBotUsername = QString();
|
||||
}
|
||||
|
||||
int32 pos = textCursor().position();
|
||||
if (textCursor().anchor() != pos) return;
|
||||
|
||||
// check mention / hashtag / bot command
|
||||
QTextDocument *doc(document());
|
||||
QTextBlock block = doc->findBlock(pos);
|
||||
|
@ -888,14 +906,18 @@ void FlatTextarea::step_appearance(float64 ms, bool timer) {
|
|||
if (timer) update();
|
||||
}
|
||||
|
||||
void FlatTextarea::setPlaceholder(const QString &ph) {
|
||||
void FlatTextarea::setPlaceholder(const QString &ph, int32 afterSymbols) {
|
||||
_ph = ph;
|
||||
_phelided = _st.font->elided(_ph, width() - _st.textMrg.left() - _st.textMrg.right() - _st.phPos.x() - 1);
|
||||
if (_phAfter != afterSymbols) {
|
||||
_phAfter = afterSymbols;
|
||||
updatePlaceholder();
|
||||
}
|
||||
_phelided = _st.font->elided(_ph, width() - _st.textMrg.left() - _st.textMrg.right() - _st.phPos.x() - 1 - (_phAfter ? _st.font->width(getLastText().mid(0, _phAfter)) : 0));
|
||||
if (_phVisible) update();
|
||||
}
|
||||
|
||||
void FlatTextarea::updatePlaceholder() {
|
||||
bool vis = getLastText().isEmpty();
|
||||
bool vis = (getLastText().size() <= _phAfter);
|
||||
if (vis == _phVisible) return;
|
||||
|
||||
a_phLeft.start(vis ? 0 : _st.phShift);
|
||||
|
|
|
@ -51,8 +51,9 @@ public:
|
|||
const QString &getLastText() const {
|
||||
return _oldtext;
|
||||
}
|
||||
void setPlaceholder(const QString &ph);
|
||||
void setPlaceholder(const QString &ph, int32 afterSymbols = 0);
|
||||
void updatePlaceholder();
|
||||
void finishPlaceholder();
|
||||
|
||||
QRect getTextRect() const;
|
||||
int32 fakeMargin() const;
|
||||
|
@ -78,7 +79,7 @@ public:
|
|||
QMimeData *createMimeDataFromSelection() const;
|
||||
void setCtrlEnterSubmit(bool ctrlEnterSubmit);
|
||||
|
||||
void setTextFast(const QString &text);
|
||||
void setTextFast(const QString &text, bool withUndo = false);
|
||||
|
||||
public slots:
|
||||
|
||||
|
@ -124,6 +125,7 @@ private:
|
|||
bool _ctrlEnterSubmit;
|
||||
|
||||
QString _ph, _phelided, _oldtext;
|
||||
int32 _phAfter;
|
||||
bool _phVisible;
|
||||
anim::ivalue a_phLeft;
|
||||
anim::fvalue a_phAlpha;
|
||||
|
|
|
@ -591,6 +591,10 @@ Image *getImage(const QByteArray &filecontent, QByteArray format, const QPixmap
|
|||
return new Image(filecontent, format, pixmap);
|
||||
}
|
||||
|
||||
Image *getImage(int32 width, int32 height) {
|
||||
return new DelayedStorageImage(width, height);
|
||||
}
|
||||
|
||||
void clearStorageImages() {
|
||||
for (StorageImages::const_iterator i = storageImages.cbegin(), e = storageImages.cend(); i != e; ++i) {
|
||||
delete i.value();
|
||||
|
@ -644,6 +648,13 @@ void RemoteImage::doCheckload() const {
|
|||
_forgot = false;
|
||||
}
|
||||
|
||||
void RemoteImage::loadLocal() {
|
||||
if (loaded() || amLoading()) return;
|
||||
|
||||
_loader = createLoader(LoadFromLocalOnly, true);
|
||||
if (_loader) _loader->start();
|
||||
}
|
||||
|
||||
void RemoteImage::setData(QByteArray &bytes, const QByteArray &bytesFormat) {
|
||||
QBuffer buffer(&bytes);
|
||||
|
||||
|
@ -781,6 +792,89 @@ FileLoader *StorageImage::createLoader(LoadFromCloudSetting fromCloud, bool auto
|
|||
return new mtpFileLoader(&_location, _size, fromCloud, autoLoading);
|
||||
}
|
||||
|
||||
DelayedStorageImage::DelayedStorageImage() : StorageImage(StorageImageLocation())
|
||||
, _loadRequested(false)
|
||||
, _loadCancelled(false)
|
||||
, _loadFromCloud(false) {
|
||||
}
|
||||
|
||||
DelayedStorageImage::DelayedStorageImage(int32 w, int32 h) : StorageImage(StorageImageLocation(w, h, 0, 0, 0, 0))
|
||||
, _loadRequested(false)
|
||||
, _loadCancelled(false)
|
||||
, _loadFromCloud(false) {
|
||||
}
|
||||
|
||||
DelayedStorageImage::DelayedStorageImage(QByteArray &bytes) : StorageImage(StorageImageLocation(), bytes)
|
||||
, _loadRequested(false)
|
||||
, _loadCancelled(false)
|
||||
, _loadFromCloud(false) {
|
||||
}
|
||||
|
||||
void DelayedStorageImage::setStorageLocation(const StorageImageLocation location) {
|
||||
_location = location;
|
||||
if (_loadRequested) {
|
||||
if (!_loadCancelled) {
|
||||
if (_loadFromCloud) {
|
||||
load();
|
||||
} else {
|
||||
loadLocal();
|
||||
}
|
||||
}
|
||||
_loadRequested = false;
|
||||
}
|
||||
}
|
||||
|
||||
void DelayedStorageImage::automaticLoad(const HistoryItem *item) {
|
||||
if (_location.isNull()) {
|
||||
if (!_loadCancelled && item) {
|
||||
bool loadFromCloud = false;
|
||||
if (item->history()->peer->isUser()) {
|
||||
loadFromCloud = !(cAutoDownloadPhoto() & dbiadNoPrivate);
|
||||
} else {
|
||||
loadFromCloud = !(cAutoDownloadPhoto() & dbiadNoGroups);
|
||||
}
|
||||
|
||||
if (_loadRequested) {
|
||||
if (loadFromCloud) _loadFromCloud = loadFromCloud;
|
||||
} else {
|
||||
_loadFromCloud = loadFromCloud;
|
||||
_loadRequested = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
StorageImage::automaticLoad(item);
|
||||
}
|
||||
}
|
||||
|
||||
void DelayedStorageImage::automaticLoadSettingsChanged() {
|
||||
if (_loadCancelled) _loadCancelled = false;
|
||||
StorageImage::automaticLoadSettingsChanged();
|
||||
}
|
||||
|
||||
void DelayedStorageImage::load(bool loadFirst, bool prior) {
|
||||
if (_location.isNull()) {
|
||||
_loadRequested = _loadFromCloud = true;
|
||||
} else {
|
||||
StorageImage::load(loadFirst, prior);
|
||||
}
|
||||
}
|
||||
|
||||
void DelayedStorageImage::loadEvenCancelled(bool loadFirst, bool prior) {
|
||||
_loadCancelled = false;
|
||||
StorageImage::loadEvenCancelled(loadFirst, prior);
|
||||
}
|
||||
|
||||
bool DelayedStorageImage::displayLoading() const {
|
||||
return _location.isNull() ? true : StorageImage::displayLoading();
|
||||
}
|
||||
|
||||
void DelayedStorageImage::cancel() {
|
||||
if (_loadRequested) {
|
||||
_loadRequested = false;
|
||||
}
|
||||
StorageImage::cancel();
|
||||
}
|
||||
|
||||
StorageImage *getImage(const StorageImageLocation &location, int32 size) {
|
||||
StorageKey key(storageKey(location));
|
||||
StorageImages::const_iterator i = storageImages.constFind(key);
|
||||
|
|
|
@ -109,6 +109,8 @@ inline bool operator!=(const StorageImageLocation &a, const StorageImageLocation
|
|||
|
||||
QPixmap imagePix(QImage img, int32 w, int32 h, bool smooth, bool blurred, bool rounded, int32 outerw, int32 outerh);
|
||||
|
||||
class DelayedStorageImage;
|
||||
|
||||
class HistoryItem;
|
||||
class Image {
|
||||
public:
|
||||
|
@ -183,6 +185,13 @@ public:
|
|||
return _saved;
|
||||
}
|
||||
|
||||
virtual DelayedStorageImage *toDelayedStorageImage() {
|
||||
return 0;
|
||||
}
|
||||
virtual const DelayedStorageImage *toDelayedStorageImage() const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual ~Image();
|
||||
|
||||
protected:
|
||||
|
@ -209,6 +218,7 @@ Image *getImage(const QString &file, QByteArray format);
|
|||
Image *getImage(const QByteArray &filecontent, QByteArray format);
|
||||
Image *getImage(const QPixmap &pixmap, QByteArray format);
|
||||
Image *getImage(const QByteArray &filecontent, QByteArray format, const QPixmap &pixmap);
|
||||
Image *getImage(int32 width, int32 height);
|
||||
|
||||
typedef QPair<uint64, uint64> StorageKey;
|
||||
inline uint64 storageMix32To64(int32 a, int32 b) {
|
||||
|
@ -256,6 +266,7 @@ protected:
|
|||
void checkload() const {
|
||||
doCheckload();
|
||||
}
|
||||
void loadLocal();
|
||||
|
||||
private:
|
||||
mutable FileLoader *_loader;
|
||||
|
@ -282,12 +293,45 @@ public:
|
|||
return _location;
|
||||
}
|
||||
|
||||
private:
|
||||
protected:
|
||||
StorageImageLocation _location;
|
||||
int32 _size;
|
||||
|
||||
};
|
||||
|
||||
class DelayedStorageImage : public StorageImage {
|
||||
public:
|
||||
|
||||
DelayedStorageImage();
|
||||
DelayedStorageImage(int32 w, int32 h);
|
||||
DelayedStorageImage(QByteArray &bytes);
|
||||
|
||||
void setStorageLocation(const StorageImageLocation location);
|
||||
|
||||
virtual DelayedStorageImage *toDelayedStorageImage() {
|
||||
return this;
|
||||
}
|
||||
virtual const DelayedStorageImage *toDelayedStorageImage() const {
|
||||
return this;
|
||||
}
|
||||
|
||||
void automaticLoad(const HistoryItem *item); // auto load photo
|
||||
void automaticLoadSettingsChanged();
|
||||
|
||||
bool loading() const {
|
||||
return _location.isNull() ? _loadRequested : StorageImage::loading();
|
||||
}
|
||||
bool displayLoading() const;
|
||||
void cancel();
|
||||
|
||||
void load(bool loadFirst = false, bool prior = true);
|
||||
void loadEvenCancelled(bool loadFirst = false, bool prior = true);
|
||||
|
||||
private:
|
||||
bool _loadRequested, _loadCancelled, _loadFromCloud;
|
||||
|
||||
};
|
||||
|
||||
StorageImage *getImage(const StorageImageLocation &location, int32 size = 0);
|
||||
StorageImage *getImage(const StorageImageLocation &location, const QByteArray &bytes);
|
||||
Image *getImage(int32 width, int32 height, const MTPFileLocation &location);
|
||||
|
@ -327,8 +371,22 @@ public:
|
|||
ImagePtr(const StorageImageLocation &location, const QByteArray &bytes) : Parent(getImage(location, bytes)) {
|
||||
}
|
||||
ImagePtr(int32 width, int32 height, const MTPFileLocation &location, ImagePtr def = ImagePtr());
|
||||
ImagePtr(int32 width, int32 height) : Parent(getImage(width, height)) {
|
||||
}
|
||||
};
|
||||
|
||||
inline QSize resizeKeepAspect(int32 width, int32 height, int32 towidth, int32 toheight) {
|
||||
int32 w = qMax(width, 1), h = qMax(height, 1);
|
||||
if (w * toheight > h * towidth) {
|
||||
h = qRound(h * towidth / float64(w));
|
||||
w = towidth;
|
||||
} else {
|
||||
w = qRound(w * toheight / float64(h));
|
||||
h = toheight;
|
||||
}
|
||||
return QSize(qMax(w, 1), qMax(h, 1));
|
||||
}
|
||||
|
||||
void clearStorageImages();
|
||||
void clearAllImages();
|
||||
int64 imageCacheSize();
|
||||
|
|
|
@ -4432,6 +4432,7 @@ HistoryGif::HistoryGif(DocumentData *document, const QString &caption, const His
|
|||
}
|
||||
|
||||
HistoryGif::HistoryGif(const HistoryGif &other) : HistoryFileMedia()
|
||||
, _parent(0)
|
||||
, _data(other._data)
|
||||
, _thumbw(other._thumbw)
|
||||
, _thumbh(other._thumbh)
|
||||
|
@ -4442,6 +4443,7 @@ HistoryGif::HistoryGif(const HistoryGif &other) : HistoryFileMedia()
|
|||
}
|
||||
|
||||
void HistoryGif::initDimensions(const HistoryItem *parent) {
|
||||
_parent = parent;
|
||||
if (_caption.hasSkipBlock()) {
|
||||
_caption.setSkipBlock(parent->skipBlockWidth(), parent->skipBlockHeight());
|
||||
}
|
||||
|
@ -4556,7 +4558,7 @@ void HistoryGif::draw(Painter &p, const HistoryItem *parent, const QRect &r, boo
|
|||
if (_width < st::msgPadding.left() + st::msgPadding.right() + 1) return;
|
||||
|
||||
_data->automaticLoad(parent);
|
||||
bool loaded = _data->loaded(), displayLoading = _data->displayLoading();
|
||||
bool loaded = _data->loaded(), displayLoading = (parent->id < 0) || _data->displayLoading();
|
||||
if (loaded && !gif() && _gif != BadClipReader && cAutoPlayGif()) {
|
||||
const_cast<HistoryGif*>(this)->playInline(const_cast<HistoryItem*>(parent));
|
||||
if (gif()) _gif->setAutoplay();
|
||||
|
@ -4570,11 +4572,11 @@ void HistoryGif::draw(Painter &p, const HistoryItem *parent, const QRect &r, boo
|
|||
|
||||
bool animating = (gif() && _gif->started());
|
||||
|
||||
if (!animating || _data->uploading()) {
|
||||
if (!animating || parent->id < 0) {
|
||||
if (displayLoading) {
|
||||
ensureAnimation(parent);
|
||||
if (!_animation->radial.animating()) {
|
||||
_animation->radial.start(_data->progress());
|
||||
_animation->radial.start(dataProgress());
|
||||
}
|
||||
}
|
||||
updateStatusText(parent);
|
||||
|
@ -4606,7 +4608,7 @@ void HistoryGif::draw(Painter &p, const HistoryItem *parent, const QRect &r, boo
|
|||
}
|
||||
|
||||
if (radial || (!_gif && ((!loaded && !_data->loading()) || !cAutoPlayGif())) || (_gif == BadClipReader)) {
|
||||
float64 radialOpacity = (radial && loaded && !_data->uploading()) ? _animation->radial.opacity() : 1;
|
||||
float64 radialOpacity = (radial && loaded && parent->id > 0) ? _animation->radial.opacity() : 1;
|
||||
QRect inner(rthumb.x() + (rthumb.width() - st::msgFileSize) / 2, rthumb.y() + (rthumb.height() - st::msgFileSize) / 2, st::msgFileSize, st::msgFileSize);
|
||||
p.setPen(Qt::NoPen);
|
||||
if (selected) {
|
||||
|
@ -4641,7 +4643,7 @@ void HistoryGif::draw(Painter &p, const HistoryItem *parent, const QRect &r, boo
|
|||
_animation->radial.draw(p, rinner, st::msgFileRadialLine, selected ? st::msgInBgSelected : st::msgInBg);
|
||||
}
|
||||
|
||||
if (!animating || _data->uploading()) {
|
||||
if (!animating || parent->id < 0) {
|
||||
int32 statusX = skipx + st::msgDateImgDelta + st::msgDateImgPadding.x(), statusY = skipy + st::msgDateImgDelta + st::msgDateImgPadding.y();
|
||||
int32 statusW = st::normalFont->width(_statusText) + 2 * st::msgDateImgPadding.x();
|
||||
int32 statusH = st::normalFont->height + 2 * st::msgDateImgPadding.y();
|
||||
|
@ -4784,6 +4786,18 @@ HistoryGif::~HistoryGif() {
|
|||
}
|
||||
}
|
||||
|
||||
float64 HistoryGif::dataProgress() const {
|
||||
return (_data->uploading() || !_parent || _parent->id > 0) ? _data->progress() : 0;
|
||||
}
|
||||
|
||||
bool HistoryGif::dataFinished() const {
|
||||
return (!_parent || _parent->id > 0) ? (!_data->loading() && !_data->uploading()) : false;
|
||||
}
|
||||
|
||||
bool HistoryGif::dataLoaded() const {
|
||||
return (!_parent || _parent->id > 0) ? _data->loaded() : false;
|
||||
}
|
||||
|
||||
HistorySticker::HistorySticker(DocumentData *document) : HistoryMedia()
|
||||
, _pixw(1)
|
||||
, _pixh(1)
|
||||
|
@ -5807,12 +5821,39 @@ int32 HistoryImageLink::fullHeight() const {
|
|||
return st::minPhotoSize;
|
||||
}
|
||||
|
||||
void ViaInlineBotLink::onClick(Qt::MouseButton button) const {
|
||||
App::insertBotCommand('@' + _bot->username);
|
||||
}
|
||||
|
||||
HistoryMessageVia::HistoryMessageVia(int32 userId)
|
||||
: bot(App::userLoaded(peerFromUser(userId)))
|
||||
, width(0)
|
||||
, fullWidth(st::msgServiceNameFont->width(qsl("via @") + bot->username))
|
||||
, lnk(new ViaInlineBotLink(bot)) {
|
||||
}
|
||||
|
||||
bool HistoryMessageVia::isNull() const {
|
||||
return !bot || bot->username.isEmpty();
|
||||
}
|
||||
|
||||
void HistoryMessageVia::resize(int32 availw) {
|
||||
if (width < fullWidth && availw > width) {
|
||||
if (availw < fullWidth) {
|
||||
text = st::msgServiceNameFont->elided(qsl("via @") + bot->username, availw);
|
||||
width = st::msgServiceNameFont->width(text);
|
||||
} else {
|
||||
text = qsl("via @") + bot->username;
|
||||
width = fullWidth;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HistoryMessage::HistoryMessage(History *history, HistoryBlock *block, const MTPDmessage &msg) :
|
||||
HistoryItem(history, block, msg.vid.v, msg.vflags.v, ::date(msg.vdate), msg.has_from_id() ? msg.vfrom_id.v : 0)
|
||||
, _text(st::msgMinWidth)
|
||||
, _textWidth(0)
|
||||
, _textHeight(0)
|
||||
, _viaBot(msg.has_via_bot_id() ? App::userLoaded(peerFromUser(msg.vvia_bot_id)) : 0)
|
||||
, _via(msg.has_via_bot_id() ? new HistoryMessageVia(msg.vvia_bot_id.v) : 0)
|
||||
, _media(0)
|
||||
, _views(msg.has_views() ? msg.vviews.v : -1) {
|
||||
QString text(textClean(qs(msg.vmessage)));
|
||||
|
@ -5826,7 +5867,7 @@ HistoryItem(history, block, msgId, flags, date, from)
|
|||
, _text(st::msgMinWidth)
|
||||
, _textWidth(0)
|
||||
, _textHeight(0)
|
||||
, _viaBot(viaBotId ? App::userLoaded(peerFromUser(viaBotId)) : 0)
|
||||
, _via(viaBotId ? new HistoryMessageVia(viaBotId) : 0)
|
||||
, _media(0)
|
||||
, _views(fromChannel() ? 1 : -1) {
|
||||
initTime();
|
||||
|
@ -5842,7 +5883,7 @@ HistoryItem(history, block, msgId, flags, date, from)
|
|||
, _text(st::msgMinWidth)
|
||||
, _textWidth(0)
|
||||
, _textHeight(0)
|
||||
, _viaBot(viaBotId ? App::userLoaded(peerFromUser(viaBotId)) : 0)
|
||||
, _via(viaBotId ? new HistoryMessageVia(viaBotId) : 0)
|
||||
, _media(0)
|
||||
, _views(fromChannel() ? 1 : -1) {
|
||||
initTime();
|
||||
|
@ -5855,7 +5896,7 @@ HistoryItem(history, block, msgId, flags, date, from)
|
|||
, _text(st::msgMinWidth)
|
||||
, _textWidth(0)
|
||||
, _textHeight(0)
|
||||
, _viaBot(viaBotId ? App::userLoaded(peerFromUser(viaBotId)) : 0)
|
||||
, _via(viaBotId ? new HistoryMessageVia(viaBotId) : 0)
|
||||
, _media(0)
|
||||
, _views(fromChannel() ? 1 : -1) {
|
||||
initTime();
|
||||
|
@ -5994,6 +6035,11 @@ void HistoryMessage::initDimensions() {
|
|||
if (maxw > _maxw) _maxw = maxw;
|
||||
_minh += _media->minHeight();
|
||||
}
|
||||
if (via()) {
|
||||
if (st::msgPadding.left() + via()->fullWidth + st::msgPadding.right() > _maxw) {
|
||||
_maxw = st::msgPadding.left() + via()->fullWidth + st::msgPadding.right() > _maxw;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
_media->initDimensions(this);
|
||||
_maxw = _media->maxWidth();
|
||||
|
@ -6251,7 +6297,7 @@ void HistoryMessage::draw(Painter &p, const QRect &r, uint32 selection, uint64 m
|
|||
App::roundRect(p, r, bg, cors, &sh);
|
||||
|
||||
if (displayFromName()) {
|
||||
p.setFont(st::msgNameFont->f);
|
||||
p.setFont(st::msgNameFont);
|
||||
if (fromChannel()) {
|
||||
p.setPen(selected ? st::msgInServiceFgSelected : st::msgInServiceFg);
|
||||
} else {
|
||||
|
@ -6260,6 +6306,7 @@ void HistoryMessage::draw(Painter &p, const QRect &r, uint32 selection, uint64 m
|
|||
_from->nameText.drawElided(p, r.left() + st::msgPadding.left(), r.top() + st::msgPadding.top(), width - st::msgPadding.left() - st::msgPadding.right());
|
||||
r.setTop(r.top() + st::msgNameFont->height);
|
||||
}
|
||||
|
||||
QRect trect(r.marginsAdded(-st::msgPadding));
|
||||
drawMessageText(p, trect, selection);
|
||||
|
||||
|
@ -6286,7 +6333,15 @@ void HistoryMessage::draw(Painter &p, const QRect &r, uint32 selection, uint64 m
|
|||
textstyleRestore();
|
||||
}
|
||||
|
||||
void HistoryMessage::drawMessageText(Painter &p, const QRect &trect, uint32 selection) const {
|
||||
void HistoryMessage::drawMessageText(Painter &p, QRect trect, uint32 selection) const {
|
||||
bool outbg = out() && !fromChannel(), selected = (selection == FullSelection);
|
||||
if (via()) {
|
||||
p.setFont(st::msgServiceNameFont);
|
||||
p.setPen((selected ? (outbg ? st::msgOutServiceFgSelected : st::msgInServiceFgSelected) : (outbg ? st::msgOutServiceFg : st::msgInServiceFg))->p);
|
||||
p.drawTextLeft(trect.left(), trect.top(), _history->width, via()->text);
|
||||
trect.setY(trect.y() + st::msgServiceNameFont->height);
|
||||
}
|
||||
|
||||
p.setPen(st::msgColor->p);
|
||||
p.setFont(st::msgFont->f);
|
||||
uint16 selectedFrom = (selection == FullSelection) ? 0 : (selection >> 16) & 0xFFFF;
|
||||
|
@ -6330,6 +6385,14 @@ int32 HistoryMessage::resize(int32 width) {
|
|||
_height += st::msgNameFont->height;
|
||||
}
|
||||
}
|
||||
if (via()) {
|
||||
via()->resize(width - st::msgPadding.left() - st::msgPadding.right());
|
||||
if (emptyText() && !displayFromName()) {
|
||||
_height += st::msgPadding.top() + st::msgNameFont->height + st::mediaHeaderSkip;
|
||||
} else {
|
||||
_height += st::msgNameFont->height;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
_height = _media->resize(width, this);
|
||||
}
|
||||
|
@ -6390,7 +6453,6 @@ void HistoryMessage::getState(TextLinkPtr &lnk, HistoryCursorState &state, int32
|
|||
}
|
||||
r.setTop(r.top() + st::msgNameFont->height);
|
||||
}
|
||||
|
||||
getStateFromMessageText(lnk, state, x, y, r);
|
||||
} else {
|
||||
_media->getState(lnk, state, x - left, y - st::msgMargin.top(), this);
|
||||
|
@ -6401,6 +6463,15 @@ void HistoryMessage::getStateFromMessageText(TextLinkPtr &lnk, HistoryCursorStat
|
|||
bool inDate = false;
|
||||
|
||||
QRect trect(r.marginsAdded(-st::msgPadding));
|
||||
|
||||
if (via()) {
|
||||
if (x >= trect.left() && y >= trect.top() && y < trect.top() + st::msgNameFont->height && x < trect.left() + via()->width) {
|
||||
lnk = via()->lnk;
|
||||
return;
|
||||
}
|
||||
trect.setTop(trect.top() + st::msgNameFont->height);
|
||||
}
|
||||
|
||||
TextLinkPtr medialnk;
|
||||
if (_media && _media->isDisplayed()) {
|
||||
if (!_media->customInfoLayout()) {
|
||||
|
@ -6443,6 +6514,9 @@ void HistoryMessage::getSymbol(uint16 &symbol, bool &after, bool &upon, int32 x,
|
|||
if (displayFromName()) { // from user left name
|
||||
r.setTop(r.top() + st::msgNameFont->height);
|
||||
}
|
||||
if (via()) {
|
||||
r.setTop(r.top() + st::msgNameFont->height);
|
||||
}
|
||||
QRect trect(r.marginsAdded(-st::msgPadding));
|
||||
if (_media && _media->isDisplayed()) {
|
||||
trect.setBottom(trect.bottom() - _media->height());
|
||||
|
@ -6489,8 +6563,9 @@ QString HistoryMessage::notificationText() const {
|
|||
HistoryMessage::~HistoryMessage() {
|
||||
if (_media) {
|
||||
_media->unregItem(this);
|
||||
delete _media;
|
||||
deleteAndMark(_media);
|
||||
}
|
||||
deleteAndMark(_via);
|
||||
if (_flags & MTPDmessage::flag_reply_markup) {
|
||||
App::clearReplyMarkup(channelId(), id);
|
||||
}
|
||||
|
@ -6506,7 +6581,7 @@ HistoryForwarded::HistoryForwarded(History *history, HistoryBlock *block, const
|
|||
}
|
||||
|
||||
HistoryForwarded::HistoryForwarded(History *history, HistoryBlock *block, MsgId id, QDateTime date, int32 from, HistoryMessage *msg)
|
||||
: HistoryMessage(history, block, id, newMessageFlags(history->peer) | (!history->peer->isChannel() && msg->getMedia() && (msg->getMedia()->type() == MediaTypeAudio/* || msg->getMedia()->type() == MediaTypeVideo*/) ? MTPDmessage::flag_media_unread : 0), msg->viaBot() ? peerToUser(msg->viaBot()->id) : 0, date, from, msg->HistoryMessage::originalText(), msg->HistoryMessage::originalEntities(), msg->getMedia())
|
||||
: HistoryMessage(history, block, id, newMessageFlags(history->peer) | (!history->peer->isChannel() && msg->getMedia() && (msg->getMedia()->type() == MediaTypeAudio/* || msg->getMedia()->type() == MediaTypeVideo*/) ? MTPDmessage::flag_media_unread : 0), msg->via() ? peerToUser(msg->viaBot()->id) : 0, date, from, msg->HistoryMessage::originalText(), msg->HistoryMessage::originalEntities(), msg->getMedia())
|
||||
, fwdDate(msg->dateForwarded())
|
||||
, fwdFrom(msg->fromForwarded())
|
||||
, fwdFromVersion(fwdFrom->nameVersion)
|
||||
|
@ -6548,7 +6623,7 @@ void HistoryForwarded::drawForwardedFrom(Painter &p, int32 x, int32 y, int32 w,
|
|||
|
||||
bool outbg = out() && !fromChannel();
|
||||
p.setPen((selected ? (outbg ? st::msgOutServiceFgSelected : st::msgInServiceFgSelected) : (outbg ? st::msgOutServiceFg : st::msgInServiceFg))->p);
|
||||
p.setFont(serviceFont->f);
|
||||
p.setFont(serviceFont);
|
||||
|
||||
if (w >= fromWidth) {
|
||||
p.drawText(x, y + serviceFont->ascent, lang(lng_forwarded_from));
|
||||
|
@ -6560,24 +6635,25 @@ void HistoryForwarded::drawForwardedFrom(Painter &p, int32 x, int32 y, int32 w,
|
|||
}
|
||||
}
|
||||
|
||||
void HistoryForwarded::drawMessageText(Painter &p, const QRect &trect, uint32 selection) const {
|
||||
QRect realtrect(trect);
|
||||
void HistoryForwarded::drawMessageText(Painter &p, QRect trect, uint32 selection) const {
|
||||
if (displayForwardedFrom()) {
|
||||
drawForwardedFrom(p, realtrect.x(), realtrect.y(), realtrect.width(), (selection == FullSelection));
|
||||
realtrect.setY(trect.y() + st::msgServiceNameFont->height);
|
||||
drawForwardedFrom(p, trect.x(), trect.y(), trect.width(), (selection == FullSelection));
|
||||
trect.setY(trect.y() + st::msgServiceNameFont->height);
|
||||
}
|
||||
HistoryMessage::drawMessageText(p, realtrect, selection);
|
||||
HistoryMessage::drawMessageText(p, trect, selection);
|
||||
}
|
||||
|
||||
int32 HistoryForwarded::resize(int32 width) {
|
||||
HistoryMessage::resize(width);
|
||||
if (drawBubble() && displayForwardedFrom()) {
|
||||
if (emptyText() && !displayFromName()) {
|
||||
if (drawBubble()) {
|
||||
if (displayForwardedFrom()) {
|
||||
if (emptyText() && !displayFromName() && !via()) {
|
||||
_height += st::msgPadding.top() + st::msgServiceNameFont->height + st::mediaHeaderSkip;
|
||||
} else {
|
||||
_height += st::msgServiceNameFont->height;
|
||||
}
|
||||
}
|
||||
}
|
||||
return _height;
|
||||
}
|
||||
|
||||
|
@ -6836,21 +6912,20 @@ void HistoryReply::drawReplyTo(Painter &p, int32 x, int32 y, int32 w, bool selec
|
|||
}
|
||||
}
|
||||
|
||||
void HistoryReply::drawMessageText(Painter &p, const QRect &trect, uint32 selection) const {
|
||||
void HistoryReply::drawMessageText(Painter &p, QRect trect, uint32 selection) const {
|
||||
int32 h = st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom();
|
||||
|
||||
drawReplyTo(p, trect.x(), trect.y(), trect.width(), (selection == FullSelection));
|
||||
|
||||
QRect realtrect(trect);
|
||||
realtrect.setY(trect.y() + h);
|
||||
HistoryMessage::drawMessageText(p, realtrect, selection);
|
||||
trect.setY(trect.y() + h);
|
||||
HistoryMessage::drawMessageText(p, trect, selection);
|
||||
}
|
||||
|
||||
int32 HistoryReply::resize(int32 width) {
|
||||
HistoryMessage::resize(width);
|
||||
|
||||
if (drawBubble()) {
|
||||
if (emptyText() && !displayFromName()) {
|
||||
if (emptyText() && !displayFromName() && !via()) {
|
||||
_height += st::msgPadding.top() + st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom() + st::mediaHeaderSkip;
|
||||
} else {
|
||||
_height += st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom();
|
||||
|
|
|
@ -807,6 +807,10 @@ public:
|
|||
virtual int32 resize(int32 width) = 0; // return new height
|
||||
virtual void draw(Painter &p, const QRect &r, uint32 selection, uint64 ms) const = 0;
|
||||
|
||||
virtual UserData *viaBot() const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
History *history() const {
|
||||
return _history;
|
||||
}
|
||||
|
@ -1311,7 +1315,7 @@ public:
|
|||
return _caption.original();
|
||||
}
|
||||
bool needsBubble(const HistoryItem *parent) const {
|
||||
return !_caption.isEmpty() || parent->toHistoryReply();
|
||||
return !_caption.isEmpty() || parent->toHistoryReply() || parent->viaBot();
|
||||
}
|
||||
bool customInfoLayout() const {
|
||||
return _caption.isEmpty();
|
||||
|
@ -1380,7 +1384,7 @@ public:
|
|||
ImagePtr replyPreview();
|
||||
|
||||
bool needsBubble(const HistoryItem *parent) const {
|
||||
return !_caption.isEmpty() || parent->toHistoryReply();
|
||||
return !_caption.isEmpty() || parent->toHistoryReply() || parent->viaBot();
|
||||
}
|
||||
bool customInfoLayout() const {
|
||||
return _caption.isEmpty();
|
||||
|
@ -1616,7 +1620,7 @@ public:
|
|||
return _caption.original();
|
||||
}
|
||||
bool needsBubble(const HistoryItem *parent) const {
|
||||
return !_caption.isEmpty() || parent->toHistoryReply();
|
||||
return !_caption.isEmpty() || parent->toHistoryReply() || parent->viaBot();
|
||||
}
|
||||
bool customInfoLayout() const {
|
||||
return _caption.isEmpty();
|
||||
|
@ -1632,18 +1636,13 @@ public:
|
|||
|
||||
protected:
|
||||
|
||||
float64 dataProgress() const {
|
||||
return _data->progress();
|
||||
}
|
||||
bool dataFinished() const {
|
||||
return !_data->loading() && !_data->uploading();
|
||||
}
|
||||
bool dataLoaded() const {
|
||||
return _data->loaded();
|
||||
}
|
||||
float64 dataProgress() const;
|
||||
bool dataFinished() const;
|
||||
bool dataLoaded() const;
|
||||
|
||||
private:
|
||||
|
||||
const HistoryItem *_parent;
|
||||
DocumentData *_data;
|
||||
int32 _thumbw, _thumbh;
|
||||
Text _caption;
|
||||
|
@ -1885,7 +1884,7 @@ public:
|
|||
}
|
||||
|
||||
bool needsBubble(const HistoryItem *parent) const {
|
||||
return !_title.isEmpty() || !_description.isEmpty() || parent->toHistoryForwarded() || parent->toHistoryReply();
|
||||
return !_title.isEmpty() || !_description.isEmpty() || parent->toHistoryForwarded() || parent->toHistoryReply() || parent->viaBot();
|
||||
}
|
||||
bool customInfoLayout() const {
|
||||
return true;
|
||||
|
@ -1901,6 +1900,33 @@ private:
|
|||
|
||||
};
|
||||
|
||||
class ViaInlineBotLink : public ITextLink {
|
||||
TEXT_LINK_CLASS(ViaInlineBotLink)
|
||||
|
||||
public:
|
||||
ViaInlineBotLink(UserData *bot) : _bot(bot) {
|
||||
}
|
||||
void onClick(Qt::MouseButton button) const;
|
||||
|
||||
private:
|
||||
UserData *_bot;
|
||||
|
||||
};
|
||||
|
||||
class HistoryMessageVia {
|
||||
public:
|
||||
HistoryMessageVia(int32 userId);
|
||||
|
||||
bool isNull() const;
|
||||
void resize(int32 availw);
|
||||
|
||||
UserData *bot;
|
||||
QString text;
|
||||
int32 width, fullWidth;
|
||||
TextLinkPtr lnk;
|
||||
|
||||
};
|
||||
|
||||
class HistoryMessage : public HistoryItem {
|
||||
public:
|
||||
|
||||
|
@ -1915,8 +1941,11 @@ public:
|
|||
void initDimensions();
|
||||
void fromNameUpdated() const;
|
||||
|
||||
UserData *viaBot() const {
|
||||
return _viaBot;
|
||||
virtual HistoryMessageVia *via() const {
|
||||
return (_via && !_via->isNull()) ? _via : 0;
|
||||
}
|
||||
virtual UserData *viaBot() const {
|
||||
return via() ? via()->bot : 0;
|
||||
}
|
||||
|
||||
int32 plainMaxWidth() const;
|
||||
|
@ -1932,7 +1961,7 @@ public:
|
|||
return drawBubble();
|
||||
}
|
||||
bool displayFromName() const {
|
||||
return hasFromName() && (!emptyText() || !_media || !_media->isDisplayed() || toHistoryReply() || !_media->hideFromName());
|
||||
return hasFromName() && (!emptyText() || !_media || !_media->isDisplayed() || toHistoryReply() || viaBot() || !_media->hideFromName());
|
||||
}
|
||||
bool uploading() const {
|
||||
return _media && _media->uploading();
|
||||
|
@ -1943,7 +1972,7 @@ public:
|
|||
void setId(MsgId newId);
|
||||
void draw(Painter &p, const QRect &r, uint32 selection, uint64 ms) const;
|
||||
|
||||
virtual void drawMessageText(Painter &p, const QRect &trect, uint32 selection) const;
|
||||
virtual void drawMessageText(Painter &p, QRect trect, uint32 selection) const;
|
||||
|
||||
int32 resize(int32 width);
|
||||
bool hasPoint(int32 x, int32 y) const;
|
||||
|
@ -2036,7 +2065,7 @@ protected:
|
|||
Text _text;
|
||||
|
||||
int32 _textWidth, _textHeight;
|
||||
UserData *_viaBot;
|
||||
HistoryMessageVia *_via;
|
||||
|
||||
HistoryMedia *_media;
|
||||
QString _timeText;
|
||||
|
@ -2058,7 +2087,7 @@ public:
|
|||
|
||||
void draw(Painter &p, const QRect &r, uint32 selection, uint64 ms) const;
|
||||
void drawForwardedFrom(Painter &p, int32 x, int32 y, int32 w, bool selected) const;
|
||||
void drawMessageText(Painter &p, const QRect &trect, uint32 selection) const;
|
||||
void drawMessageText(Painter &p, QRect trect, uint32 selection) const;
|
||||
int32 resize(int32 width);
|
||||
bool hasPoint(int32 x, int32 y) const;
|
||||
void getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y) const;
|
||||
|
@ -2115,7 +2144,7 @@ public:
|
|||
|
||||
void draw(Painter &p, const QRect &r, uint32 selection, uint64 ms) const;
|
||||
void drawReplyTo(Painter &p, int32 x, int32 y, int32 w, bool selected, bool likeService = false) const;
|
||||
void drawMessageText(Painter &p, const QRect &trect, uint32 selection) const;
|
||||
void drawMessageText(Painter &p, QRect trect, uint32 selection) const;
|
||||
int32 resize(int32 width);
|
||||
bool hasPoint(int32 x, int32 y) const;
|
||||
void getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y) const;
|
||||
|
|
|
@ -956,7 +956,7 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
|||
}
|
||||
}
|
||||
QString contextMenuText = item->selectedText(FullSelection);
|
||||
if (!contextMenuText.isEmpty() && (!msg || !msg->getMedia() || _dragCursorState == HistoryInTextCursorState)) {
|
||||
if (!contextMenuText.isEmpty() && (!msg || !msg->getMedia() || (msg->getMedia()->type() != MediaTypeSticker && msg->getMedia()->type() != MediaTypeGif))) {
|
||||
_menu->addAction(lang(lng_context_copy_text), this, SLOT(copyContextText()))->setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
@ -3823,11 +3823,10 @@ void HistoryWidget::updateControlsVisibility() {
|
|||
}
|
||||
if (hasBroadcastToggle()) {
|
||||
_broadcast.show();
|
||||
_field.setPlaceholder(lang(_broadcast.checked() ? lng_broadcast_ph : lng_comment_ph));
|
||||
} else {
|
||||
_broadcast.hide();
|
||||
_field.setPlaceholder(lang((_history && _history->isChannel() && !_history->isMegagroup()) ? (_peer->asChannel()->canPublish() ? lng_broadcast_ph : lng_comment_ph) : lng_message_ph));
|
||||
}
|
||||
updateFieldPlaceholder();
|
||||
}
|
||||
if (_replyToId || readyToForward() || (_previewData && _previewData->pendingTill >= 0) || _kbReplyTo) {
|
||||
if (_replyForwardPreviewCancel.isHidden()) {
|
||||
|
@ -4442,7 +4441,7 @@ void HistoryWidget::onMuteUnmute() {
|
|||
}
|
||||
|
||||
void HistoryWidget::onBroadcastChange() {
|
||||
_field.setPlaceholder(lang(_broadcast.checked() ? lng_broadcast_ph : lng_comment_ph));
|
||||
updateFieldPlaceholder();
|
||||
}
|
||||
|
||||
void HistoryWidget::onShareContact(const PeerId &peer, UserData *contact) {
|
||||
|
@ -4838,11 +4837,12 @@ void HistoryWidget::insertBotCommand(const QString &cmd) {
|
|||
if (!bot->isUser() || !bot->asUser()->botInfo) bot = 0;
|
||||
QString username = bot ? bot->asUser()->username : QString();
|
||||
int32 botStatus = _peer->isChat() ? _peer->asChat()->botStatus : (_peer->isMegagroup() ? _peer->asChannel()->mgInfo->botStatus : -1);
|
||||
if (toInsert.indexOf('@') < 2 && !username.isEmpty() && (botStatus == 0 || botStatus == 2)) {
|
||||
if (toInsert.indexOf('@') < 0 && !username.isEmpty() && (botStatus == 0 || botStatus == 2)) {
|
||||
toInsert += '@' + username;
|
||||
}
|
||||
toInsert += ' ';
|
||||
|
||||
if (toInsert.at(0) != '@') {
|
||||
QString text = _field.getLastText();
|
||||
QRegularExpressionMatch m = QRegularExpression(qsl("^/[A-Za-z_0-9]{0,64}(@[A-Za-z_0-9]{0,32})?(\\s|$)")).match(text);
|
||||
if (m.hasMatch()) {
|
||||
|
@ -4850,11 +4850,14 @@ void HistoryWidget::insertBotCommand(const QString &cmd) {
|
|||
} else {
|
||||
text = toInsert + text;
|
||||
}
|
||||
_field.setText(text);
|
||||
_field.setTextFast(text);
|
||||
|
||||
QTextCursor cur(_field.textCursor());
|
||||
cur.movePosition(QTextCursor::End);
|
||||
_field.setTextCursor(cur);
|
||||
} else {
|
||||
_field.setTextFast(toInsert, true);
|
||||
}
|
||||
}
|
||||
|
||||
bool HistoryWidget::eventFilter(QObject *obj, QEvent *e) {
|
||||
|
@ -4951,23 +4954,21 @@ bool HistoryWidget::hasBroadcastToggle() const {
|
|||
}
|
||||
|
||||
void HistoryWidget::inlineBotResolveDone(const MTPcontacts_ResolvedPeer &result) {
|
||||
_inlineBot = 0;
|
||||
_inlineBotUsername = QString();
|
||||
if (result.type() == mtpc_contacts_resolvedPeer) {
|
||||
const MTPDcontacts_resolvedPeer &d(result.c_contacts_resolvedPeer());
|
||||
App::feedUsers(d.vusers);
|
||||
App::feedChats(d.vchats);
|
||||
PeerId peerId = peerFromMTP(d.vpeer);
|
||||
if (peerId && peerIsUser(peerId)) {
|
||||
_inlineBot = App::user(peerId);
|
||||
}
|
||||
}
|
||||
onCheckMentionDropdown();
|
||||
}
|
||||
|
||||
bool HistoryWidget::inlineBotResolveFail(const RPCError &error) {
|
||||
bool HistoryWidget::inlineBotResolveFail(QString name, const RPCError &error) {
|
||||
if (mtpIsFlood(error)) return false;
|
||||
if (name == _inlineBotUsername) {
|
||||
_inlineBot = 0;
|
||||
onCheckMentionDropdown();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -5299,7 +5300,7 @@ void HistoryWidget::onFieldResize() {
|
|||
_cmdStart.move(_attachEmoji.x() - _cmdStart.width(), height() - kbh - _cmdStart.height());
|
||||
|
||||
_attachType.move(0, _attachDocument.y() - _attachType.height());
|
||||
_emojiPan.move(width() - _emojiPan.width(), _attachEmoji.y() - _emojiPan.height());
|
||||
_emojiPan.moveBottom(_attachEmoji.y());
|
||||
|
||||
updateListSize();
|
||||
updateField();
|
||||
|
@ -5312,6 +5313,7 @@ void HistoryWidget::onFieldFocused() {
|
|||
void HistoryWidget::onCheckMentionDropdown() {
|
||||
if (!_history || _a_show.animating()) return;
|
||||
|
||||
UserData *bot = _inlineBot;
|
||||
QString start, inlineBotUsername(_inlineBotUsername);
|
||||
_field.getMentionHashtagBotCommandStart(start, _inlineBot, _inlineBotUsername);
|
||||
if (inlineBotUsername != _inlineBotUsername) {
|
||||
|
@ -5320,8 +5322,7 @@ void HistoryWidget::onCheckMentionDropdown() {
|
|||
_inlineBotResolveRequestId = 0;
|
||||
}
|
||||
if (_inlineBot == InlineBotLookingUpData) {
|
||||
LOG(("Inline bot unknown! resolving @%1").arg(_inlineBotUsername));
|
||||
_inlineBotResolveRequestId = MTP::send(MTPcontacts_ResolveUsername(MTP_string(_inlineBotUsername)), rpcDone(&HistoryWidget::inlineBotResolveDone), rpcFail(&HistoryWidget::inlineBotResolveFail));
|
||||
_inlineBotResolveRequestId = MTP::send(MTPcontacts_ResolveUsername(MTP_string(_inlineBotUsername)), rpcDone(&HistoryWidget::inlineBotResolveDone), rpcFail(&HistoryWidget::inlineBotResolveFail, _inlineBotUsername));
|
||||
return;
|
||||
}
|
||||
} else if (_inlineBot == InlineBotLookingUpData) {
|
||||
|
@ -5329,12 +5330,19 @@ void HistoryWidget::onCheckMentionDropdown() {
|
|||
}
|
||||
|
||||
if (_inlineBot) {
|
||||
if (_inlineBot != bot) {
|
||||
updateFieldPlaceholder();
|
||||
}
|
||||
_emojiPan.queryInlineBot(_inlineBot, start);
|
||||
if (!_attachMention.isHidden()) {
|
||||
_attachMention.hideStart();
|
||||
}
|
||||
} else {
|
||||
_emojiPan.inlineBotChanged();
|
||||
if (_inlineBot != bot) {
|
||||
updateFieldPlaceholder();
|
||||
_field.finishPlaceholder();
|
||||
}
|
||||
_emojiPan.clearInlineBot();
|
||||
if (!start.isEmpty()) {
|
||||
if (start.at(0) == '#' && cRecentWriteHashtags().isEmpty() && cRecentSearchHashtags().isEmpty()) Local::readRecentHashtags();
|
||||
if (start.at(0) == '@' && _peer->isUser()) return;
|
||||
|
@ -5348,6 +5356,16 @@ void HistoryWidget::onCheckMentionDropdown() {
|
|||
}
|
||||
}
|
||||
|
||||
void HistoryWidget::updateFieldPlaceholder() {
|
||||
if (_inlineBot && _inlineBot != InlineBotLookingUpData) {
|
||||
_field.setPlaceholder(_inlineBot->botInfo->inlinePlaceholder.mid(1), _inlineBot->username.size() + 2);
|
||||
} else if (hasBroadcastToggle()) {
|
||||
_field.setPlaceholder(lang(_broadcast.checked() ? lng_broadcast_ph : lng_comment_ph));
|
||||
} else {
|
||||
_field.setPlaceholder(lang((_history && _history->isChannel() && !_history->isMegagroup()) ? (_peer->asChannel()->canPublish() ? lng_broadcast_ph : lng_comment_ph) : lng_message_ph));
|
||||
}
|
||||
}
|
||||
|
||||
void HistoryWidget::uploadImage(const QImage &img, PrepareMediaType type, FileLoadForceConfirmType confirm, const QString &source, bool withText) {
|
||||
if (!_history) return;
|
||||
|
||||
|
@ -5790,6 +5808,10 @@ void HistoryWidget::notify_historyItemLayoutChanged(const HistoryItem *item) {
|
|||
}
|
||||
}
|
||||
|
||||
void HistoryWidget::notify_automaticLoadSettingsChangedGif() {
|
||||
_emojiPan.notify_automaticLoadSettingsChangedGif();
|
||||
}
|
||||
|
||||
void HistoryWidget::resizeEvent(QResizeEvent *e) {
|
||||
_reportSpamPanel.resize(width(), _reportSpamPanel.height());
|
||||
|
||||
|
@ -5828,7 +5850,7 @@ void HistoryWidget::resizeEvent(QResizeEvent *e) {
|
|||
|
||||
_attachType.move(0, _attachDocument.y() - _attachType.height());
|
||||
_emojiPan.setMaxHeight(height() - st::dropdownDef.padding.top() - st::dropdownDef.padding.bottom() - _attachEmoji.height());
|
||||
_emojiPan.move(width() - _emojiPan.width(), _attachEmoji.y() - _emojiPan.height());
|
||||
_emojiPan.moveBottom(_attachEmoji.y());
|
||||
|
||||
switch (_attachDrag) {
|
||||
case DragStateFiles:
|
||||
|
@ -6341,18 +6363,21 @@ void HistoryWidget::onInlineResultSend(InlineResult *result, UserData *bot) {
|
|||
} else if (result->type == qstr("photo")) {
|
||||
QImage fileThumb(result->thumb->pix().toImage());
|
||||
|
||||
PreparedPhotoThumbs photoThumbs;
|
||||
QVector<MTPPhotoSize> photoSizes;
|
||||
|
||||
QPixmap thumb = (fileThumb.width() > 100 || fileThumb.height() > 100) ? QPixmap::fromImage(fileThumb.scaled(100, 100, Qt::KeepAspectRatio, Qt::SmoothTransformation), Qt::ColorOnly) : QPixmap::fromImage(fileThumb);
|
||||
photoThumbs.insert('s', thumb);
|
||||
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)));
|
||||
|
||||
QPixmap medium = (fileThumb.width() > 320 || fileThumb.height() > 320) ? QPixmap::fromImage(fileThumb.scaled(320, 320, Qt::KeepAspectRatio, Qt::SmoothTransformation), Qt::ColorOnly) : QPixmap::fromImage(fileThumb);
|
||||
photoThumbs.insert('m', medium);
|
||||
QSize medium = resizeKeepAspect(result->width, result->height, 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)));
|
||||
|
||||
MTPPhoto photo = MTP_photo(MTP_long(MTP::nonce<uint64>()), MTP_long(0), MTP_int(unixtime()), MTP_vector<MTPPhotoSize>(photoSizes));
|
||||
photoSizes.push_back(MTP_photoSize(MTP_string("x"), MTP_fileLocationUnavailable(MTP_long(0), MTP_int(0), MTP_long(0)), MTP_int(result->width), MTP_int(result->height), MTP_int(0)));
|
||||
|
||||
uint64 photoId = MTP::nonce<uint64>();
|
||||
PhotoData *ph = App::photoSet(photoId, 0, 0, unixtime(), thumbPtr, ImagePtr(medium.width(), medium.height()), ImagePtr(result->width, result->height));
|
||||
MTPPhoto photo = MTP_photo(MTP_long(photoId), MTP_long(0), MTP_int(ph->date), MTP_vector<MTPPhotoSize>(photoSizes));
|
||||
|
||||
_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 {
|
||||
|
|
|
@ -445,6 +445,8 @@ public:
|
|||
|
||||
void destroyData();
|
||||
|
||||
void updateFieldPlaceholder();
|
||||
|
||||
void uploadImage(const QImage &img, PrepareMediaType type, FileLoadForceConfirmType confirm = FileLoadNoForceConfirm, const QString &source = QString(), bool withText = false);
|
||||
void uploadFile(const QString &file, PrepareMediaType type, FileLoadForceConfirmType confirm = FileLoadNoForceConfirm, bool withText = false); // with confirmation
|
||||
void uploadFiles(const QStringList &files, PrepareMediaType type);
|
||||
|
@ -564,6 +566,7 @@ public:
|
|||
bool ui_isInlineItemBeingChosen();
|
||||
|
||||
void notify_historyItemLayoutChanged(const HistoryItem *item);
|
||||
void notify_automaticLoadSettingsChangedGif();
|
||||
void notify_botCommandsChanged(UserData *user);
|
||||
void notify_userIsBotChanged(UserData *user);
|
||||
void notify_migrateUpdated(PeerData *peer);
|
||||
|
@ -769,7 +772,7 @@ private:
|
|||
QString _inlineBotUsername;
|
||||
mtpRequestId _inlineBotResolveRequestId;
|
||||
void inlineBotResolveDone(const MTPcontacts_ResolvedPeer &result);
|
||||
bool inlineBotResolveFail(const RPCError &error);
|
||||
bool inlineBotResolveFail(QString name, const RPCError &error);
|
||||
|
||||
bool isBotStart() const;
|
||||
bool isBlocked() const;
|
||||
|
|
|
@ -1371,7 +1371,7 @@ void DeleteSavedGifLink::onClick(Qt::MouseButton button) const {
|
|||
}
|
||||
|
||||
void LayoutInlineGif::paint(Painter &p, const QRect &clip, uint32 selection, const PaintContext *context) const {
|
||||
// content_automaticLoad();
|
||||
content_automaticLoad();
|
||||
|
||||
bool loaded = content_loaded(), loading = content_loading(), displayLoading = content_displayLoading();
|
||||
if (loaded && !gif() && _gif != BadClipReader) {
|
||||
|
@ -1832,9 +1832,7 @@ void LayoutInlineWebVideo::initDimensions() {
|
|||
}
|
||||
|
||||
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;
|
||||
int32 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);
|
||||
|
@ -1849,7 +1847,6 @@ void LayoutInlineWebVideo::paint(Painter &p, const QRect &clip, uint32 selection
|
|||
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);
|
||||
|
@ -1951,7 +1948,7 @@ int32 LayoutInlineArticle::resizeGetHeight(int32 width) {
|
|||
}
|
||||
|
||||
void LayoutInlineArticle::paint(Painter &p, const QRect &clip, uint32 selection, const PaintContext *context) const {
|
||||
int32 left = 0;
|
||||
int32 left = st::emojiPanHeaderLeft - st::inlineResultsLeft;
|
||||
if (_withThumb) {
|
||||
left = st::inlineThumbSize + st::inlineThumbSkip;
|
||||
prepareThumb(st::inlineThumbSize, st::inlineThumbSize);
|
||||
|
|
|
@ -561,6 +561,8 @@ namespace {
|
|||
typedef QMap<PeerId, bool> DraftsNotReadMap;
|
||||
DraftsNotReadMap _draftsNotReadMap;
|
||||
|
||||
typedef QPair<FileKey, qint32> FileDesc; // file, size
|
||||
|
||||
typedef QMultiMap<MediaKey, FileLocation> FileLocations;
|
||||
FileLocations _fileLocations;
|
||||
typedef QPair<MediaKey, FileLocation> FileLocationPair;
|
||||
|
@ -568,6 +570,9 @@ namespace {
|
|||
FileLocationPairs _fileLocationPairs;
|
||||
typedef QMap<MediaKey, MediaKey> FileLocationAliases;
|
||||
FileLocationAliases _fileLocationAliases;
|
||||
typedef QMap<QString, FileDesc> WebFilesMap;
|
||||
WebFilesMap _webFilesMap;
|
||||
uint64 _storageWebFilesSize = 0;
|
||||
FileKey _locationsKey = 0, _reportSpamStatusesKey = 0;
|
||||
|
||||
FileKey _recentStickersKeyOld = 0, _stickersKey = 0, _savedGifsKey = 0;
|
||||
|
@ -581,7 +586,6 @@ namespace {
|
|||
|
||||
FileKey _savedPeersKey = 0;
|
||||
|
||||
typedef QPair<FileKey, qint32> FileDesc; // file, size
|
||||
typedef QMap<StorageKey, FileDesc> StorageMap;
|
||||
StorageMap _imagesMap, _stickerImagesMap, _audiosMap;
|
||||
int32 _storageImagesSize = 0, _storageStickersSize = 0, _storageAudiosSize = 0;
|
||||
|
@ -643,6 +647,12 @@ namespace {
|
|||
size += sizeof(quint64) * 2 + sizeof(quint64) * 2;
|
||||
}
|
||||
|
||||
size += sizeof(quint32); // web files count
|
||||
for (WebFilesMap::const_iterator i = _webFilesMap.cbegin(), e = _webFilesMap.cend(); i != e; ++i) {
|
||||
// url + filekey + size
|
||||
size += _stringSize(i.key()) + sizeof(quint64) + sizeof(qint32);
|
||||
}
|
||||
|
||||
EncryptedDescriptor data(size);
|
||||
for (FileLocations::const_iterator i = _fileLocations.cbegin(); i != _fileLocations.cend(); ++i) {
|
||||
data.stream << quint64(i.key().first) << quint64(i.key().second) << quint32(i.value().type) << i.value().name();
|
||||
|
@ -663,6 +673,11 @@ namespace {
|
|||
data.stream << quint64(i.key().first) << quint64(i.key().second) << quint64(i.value().first) << quint64(i.value().second);
|
||||
}
|
||||
|
||||
data.stream << quint32(_webFilesMap.size());
|
||||
for (WebFilesMap::const_iterator i = _webFilesMap.cbegin(), e = _webFilesMap.cend(); i != e; ++i) {
|
||||
data.stream << i.key() << quint64(i.value().first) << qint32(i.value().second);
|
||||
}
|
||||
|
||||
FileWriteDescriptor file(_locationsKey);
|
||||
file.writeEncrypted(data);
|
||||
}
|
||||
|
@ -710,6 +725,20 @@ namespace {
|
|||
locations.stream >> kfirst >> ksecond >> vfirst >> vsecond;
|
||||
_fileLocationAliases.insert(MediaKey(kfirst, ksecond), MediaKey(vfirst, vsecond));
|
||||
}
|
||||
|
||||
_storageWebFilesSize = 0;
|
||||
_webFilesMap.clear();
|
||||
|
||||
quint32 webLocationsCount;
|
||||
locations.stream >> webLocationsCount;
|
||||
for (quint32 i = 0; i < webLocationsCount; ++i) {
|
||||
QString url;
|
||||
quint64 key;
|
||||
qint32 size;
|
||||
locations.stream >> url >> key >> size;
|
||||
_webFilesMap.insert(url, FileDesc(key, size));
|
||||
_storageWebFilesSize += size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2154,6 +2183,8 @@ namespace Local {
|
|||
_stickerImagesMap.clear();
|
||||
_audiosMap.clear();
|
||||
_storageImagesSize = _storageStickersSize = _storageAudiosSize = 0;
|
||||
_webFilesMap.clear();
|
||||
_storageWebFilesSize = 0;
|
||||
_locationsKey = _reportSpamStatusesKey = 0;
|
||||
_recentStickersKeyOld = _stickersKey = _savedGifsKey = 0;
|
||||
_backgroundKey = _userSettingsKey = _recentHashtagsKey = _savedPeersKey = 0;
|
||||
|
@ -2437,9 +2468,10 @@ namespace Local {
|
|||
quint32 imageType;
|
||||
readFromStream(image.stream, locFirst, locSecond, imageType, imageData);
|
||||
|
||||
if (locFirst != _location.first || locSecond != _location.second) {
|
||||
return;
|
||||
}
|
||||
// we're saving files now before we have actual location
|
||||
//if (locFirst != _location.first || locSecond != _location.second) {
|
||||
// return;
|
||||
//}
|
||||
|
||||
_result = new Result(StorageFileType(imageType), imageData, _readImageFlag);
|
||||
}
|
||||
|
@ -2652,6 +2684,110 @@ namespace Local {
|
|||
return _storageAudiosSize;
|
||||
}
|
||||
|
||||
qint32 _storageWebFileSize(const QString &url, qint32 rawlen) {
|
||||
// fulllen + url + len + data
|
||||
qint32 result = sizeof(uint32) + _stringSize(url) + sizeof(quint32) + rawlen;
|
||||
if (result & 0x0F) result += 0x10 - (result & 0x0F);
|
||||
result += tdfMagicLen + sizeof(qint32) + sizeof(quint32) + 0x10 + 0x10; // magic + version + len of encrypted + part of sha1 + md5
|
||||
return result;
|
||||
}
|
||||
|
||||
void writeWebFile(const QString &url, const QByteArray &content, bool overwrite) {
|
||||
if (!_working()) return;
|
||||
|
||||
qint32 size = _storageWebFileSize(url, content.size());
|
||||
WebFilesMap::const_iterator i = _webFilesMap.constFind(url);
|
||||
if (i == _webFilesMap.cend()) {
|
||||
i = _webFilesMap.insert(url, FileDesc(genKey(UserPath), size));
|
||||
_storageWebFilesSize += size;
|
||||
_writeLocations();
|
||||
} else if (!overwrite) {
|
||||
return;
|
||||
}
|
||||
EncryptedDescriptor data(_stringSize(url) + sizeof(quint32) + sizeof(quint32) + content.size());
|
||||
data.stream << url << content;
|
||||
FileWriteDescriptor file(i.value().first, UserPath);
|
||||
file.writeEncrypted(data);
|
||||
if (i.value().second != size) {
|
||||
_storageWebFilesSize += size;
|
||||
_storageWebFilesSize -= i.value().second;
|
||||
_webFilesMap[url].second = size;
|
||||
}
|
||||
}
|
||||
|
||||
class WebFileLoadTask : public Task {
|
||||
public:
|
||||
WebFileLoadTask(const FileKey &key, const QString &url, webFileLoader *loader)
|
||||
: _key(key)
|
||||
, _url(url)
|
||||
, _loader(loader)
|
||||
, _result(0) {
|
||||
}
|
||||
void process() {
|
||||
FileReadDescriptor image;
|
||||
if (!readEncryptedFile(image, _key, UserPath)) {
|
||||
return;
|
||||
}
|
||||
|
||||
QByteArray imageData;
|
||||
QString url;
|
||||
image.stream >> url >> imageData;
|
||||
|
||||
_result = new Result(StorageFilePartial, imageData);
|
||||
}
|
||||
void finish() {
|
||||
if (_result) {
|
||||
_loader->localLoaded(_result->image, _result->format, _result->pixmap);
|
||||
} else {
|
||||
WebFilesMap::iterator j = _webFilesMap.find(_url);
|
||||
if (j != _webFilesMap.cend() && j->first == _key) {
|
||||
clearKey(j.value().first, UserPath);
|
||||
_storageWebFilesSize -= j.value().second;
|
||||
_webFilesMap.erase(j);
|
||||
}
|
||||
_loader->localLoaded(StorageImageSaved());
|
||||
}
|
||||
}
|
||||
virtual ~WebFileLoadTask() {
|
||||
deleteAndMark(_result);
|
||||
}
|
||||
|
||||
protected:
|
||||
FileKey _key;
|
||||
QString _url;
|
||||
struct Result {
|
||||
Result(StorageFileType type, const QByteArray &data) : image(type, data) {
|
||||
QByteArray guessFormat;
|
||||
pixmap = QPixmap::fromImage(App::readImage(data, &guessFormat, false), Qt::ColorOnly);
|
||||
if (!pixmap.isNull()) {
|
||||
format = guessFormat;
|
||||
}
|
||||
}
|
||||
StorageImageSaved image;
|
||||
QByteArray format;
|
||||
QPixmap pixmap;
|
||||
};
|
||||
webFileLoader *_loader;
|
||||
Result *_result;
|
||||
|
||||
};
|
||||
|
||||
TaskId startWebFileLoad(const QString &url, webFileLoader *loader) {
|
||||
WebFilesMap::const_iterator j = _webFilesMap.constFind(url);
|
||||
if (j == _webFilesMap.cend() || !_localLoader) {
|
||||
return 0;
|
||||
}
|
||||
return _localLoader->addTask(new WebFileLoadTask(j->first, url, loader));
|
||||
}
|
||||
|
||||
int32 hasWebFiles() {
|
||||
return _webFilesMap.size();
|
||||
}
|
||||
|
||||
qint64 storageWebFilesSize() {
|
||||
return _storageWebFilesSize;
|
||||
}
|
||||
|
||||
void cancelTask(TaskId id) {
|
||||
if (_localLoader) {
|
||||
_localLoader->cancelTask(id);
|
||||
|
|
|
@ -139,6 +139,11 @@ namespace Local {
|
|||
int32 hasAudios();
|
||||
qint64 storageAudiosSize();
|
||||
|
||||
void writeWebFile(const QString &url, const QByteArray &data, bool overwrite = true);
|
||||
TaskId startWebFileLoad(const QString &url, webFileLoader *loader);
|
||||
int32 hasWebFiles();
|
||||
qint64 storageWebFilesSize();
|
||||
|
||||
void cancelTask(TaskId id);
|
||||
|
||||
void writeStickers();
|
||||
|
|
|
@ -815,6 +815,10 @@ void MainWidget::notify_historyItemLayoutChanged(const HistoryItem *item) {
|
|||
if (overview) overview->notify_historyItemLayoutChanged(item);
|
||||
}
|
||||
|
||||
void MainWidget::notify_automaticLoadSettingsChangedGif() {
|
||||
history.notify_automaticLoadSettingsChangedGif();
|
||||
}
|
||||
|
||||
void MainWidget::notify_historyItemResized(const HistoryItem *item, bool scrollToIt) {
|
||||
if (!item || ((history.peer() == item->history()->peer || (history.peer() && history.peer() == item->history()->peer->migrateTo())) && !item->detached())) {
|
||||
history.notify_historyItemResized(item, scrollToIt);
|
||||
|
|
|
@ -422,6 +422,7 @@ public:
|
|||
void notify_clipStopperHidden(ClipStopperType type);
|
||||
void notify_historyItemResized(const HistoryItem *row, bool scrollToIt);
|
||||
void notify_historyItemLayoutChanged(const HistoryItem *item);
|
||||
void notify_automaticLoadSettingsChangedGif();
|
||||
|
||||
~MainWidget();
|
||||
|
||||
|
|
|
@ -628,7 +628,7 @@ void webFileLoader::onFinished(const QByteArray &data) {
|
|||
emit App::wnd()->imageLoaded();
|
||||
|
||||
if (_localStatus == LocalNotFound || _localStatus == LocalFailed) {
|
||||
//Local::writeWebFile(_url, StorageImageSaved(mtpToStorageType(_type), _data));
|
||||
Local::writeWebFile(_url, _data);
|
||||
}
|
||||
emit progress(this);
|
||||
loadNext();
|
||||
|
@ -646,7 +646,7 @@ bool webFileLoader::tryLoadLocal() {
|
|||
return true;
|
||||
}
|
||||
|
||||
_localTaskId = 0;// Local::startWebFileLoad(_url, this);
|
||||
_localTaskId = Local::startWebFileLoad(_url, this);
|
||||
if (_localStatus != LocalNotTried) {
|
||||
return _complete;
|
||||
} else if (_localTaskId) {
|
||||
|
|
|
@ -2050,6 +2050,11 @@ void InlineResult::automaticLoadGif() {
|
|||
}
|
||||
}
|
||||
|
||||
void InlineResult::automaticLoadSettingsChangedGif() {
|
||||
if (loaded() || _loader != CancelledWebFileLoader) return;
|
||||
_loader = 0;
|
||||
}
|
||||
|
||||
void InlineResult::saveFile(const QString &toFile, LoadFromCloudSetting fromCloud, bool autoLoading) {
|
||||
if (loaded()) {
|
||||
return;
|
||||
|
|
|
@ -1365,6 +1365,7 @@ public:
|
|||
ImagePtr thumb;
|
||||
|
||||
void automaticLoadGif();
|
||||
void automaticLoadSettingsChangedGif();
|
||||
void saveFile(const QString &toFile, LoadFromCloudSetting fromCloud, bool autoLoading);
|
||||
void cancelFile();
|
||||
|
||||
|
|
Loading…
Reference in New Issue