mirror of
https://github.com/vale981/tdesktop
synced 2025-03-05 17:51:41 -05:00
Add a fast share button in channels and bots.
This commit is contained in:
parent
ac99784bf7
commit
f32af6999b
13 changed files with 443 additions and 237 deletions
BIN
Telegram/Resources/icons/fast_share.png
Normal file
BIN
Telegram/Resources/icons/fast_share.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 330 B |
BIN
Telegram/Resources/icons/fast_share@2x.png
Normal file
BIN
Telegram/Resources/icons/fast_share@2x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 661 B |
|
@ -34,6 +34,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
#include "ui/toast/toast.h"
|
||||
#include "ui/widgets/multi_select.h"
|
||||
#include "history/history_media_types.h"
|
||||
#include "history/history_message.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/scroll_area.h"
|
||||
#include "window/themes/window_theme.h"
|
||||
|
@ -208,7 +209,7 @@ void ShareBox::createButtons() {
|
|||
clearButtons();
|
||||
if (_hasSelected) {
|
||||
addButton(langFactory(lng_share_confirm), [this] { onSubmit(); });
|
||||
} else {
|
||||
} else if (_copyCallback) {
|
||||
addButton(langFactory(lng_share_copy_link), [this] { onCopyLink(); });
|
||||
}
|
||||
addButton(langFactory(lng_cancel), [this] { closeBox(); });
|
||||
|
@ -840,103 +841,6 @@ QString AppendShareGameScoreUrl(const QString &url, const FullMsgId &fullId) {
|
|||
return url + shareComponent;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
void ShareGameScoreFromItem(HistoryItem *item) {
|
||||
struct ShareGameScoreData {
|
||||
ShareGameScoreData(const FullMsgId &msgId) : msgId(msgId) {
|
||||
}
|
||||
FullMsgId msgId;
|
||||
OrderedSet<mtpRequestId> requests;
|
||||
};
|
||||
auto data = MakeShared<ShareGameScoreData>(item->fullId());
|
||||
|
||||
auto copyCallback = [data]() {
|
||||
if (auto main = App::main()) {
|
||||
if (auto item = App::histItemById(data->msgId)) {
|
||||
if (auto bot = item->getMessageBot()) {
|
||||
if (auto media = item->getMedia()) {
|
||||
if (media->type() == MediaTypeGame) {
|
||||
auto shortName = static_cast<HistoryGame*>(media)->game()->shortName;
|
||||
|
||||
QApplication::clipboard()->setText(Messenger::Instance().createInternalLinkFull(bot->username + qsl("?game=") + shortName));
|
||||
|
||||
Ui::Toast::Show(lang(lng_share_game_link_copied));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
auto submitCallback = [data](const QVector<PeerData*> &result) {
|
||||
if (!data->requests.empty()) {
|
||||
return; // Share clicked already.
|
||||
}
|
||||
if (result.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto restrictedEverywhere = true;
|
||||
auto restrictedSomewhere = false;
|
||||
for_const (auto peer, result) {
|
||||
if (auto megagroup = peer->asMegagroup()) {
|
||||
if (megagroup->restrictedRights().is_send_games()) {
|
||||
restrictedSomewhere = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
restrictedEverywhere = false;
|
||||
}
|
||||
if (restrictedEverywhere) {
|
||||
Ui::show(Box<InformBox>(lang(lng_restricted_send_inline)), KeepOtherLayers);
|
||||
return;
|
||||
}
|
||||
|
||||
auto doneCallback = [data](const MTPUpdates &updates, mtpRequestId requestId) {
|
||||
if (auto main = App::main()) {
|
||||
main->sentUpdatesReceived(updates);
|
||||
}
|
||||
data->requests.remove(requestId);
|
||||
if (data->requests.empty()) {
|
||||
Ui::Toast::Show(lang(lng_share_done));
|
||||
Ui::hideLayer();
|
||||
}
|
||||
};
|
||||
|
||||
auto sendFlags = MTPmessages_ForwardMessages::Flag::f_with_my_score;
|
||||
MTPVector<MTPint> msgIds = MTP_vector<MTPint>(1, MTP_int(data->msgId.msg));
|
||||
if (auto main = App::main()) {
|
||||
if (auto item = App::histItemById(data->msgId)) {
|
||||
for_const (auto peer, result) {
|
||||
if (auto megagroup = peer->asMegagroup()) {
|
||||
if (megagroup->restrictedRights().is_send_games()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
MTPVector<MTPlong> random = MTP_vector<MTPlong>(1, rand_value<MTPlong>());
|
||||
auto request = MTPmessages_ForwardMessages(MTP_flags(sendFlags), item->history()->peer->input, msgIds, random, peer->input);
|
||||
auto callback = doneCallback;
|
||||
auto requestId = MTP::send(request, rpcDone(std::move(callback)));
|
||||
data->requests.insert(requestId);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
auto filterCallback = [](PeerData *peer) {
|
||||
if (peer->canWrite()) {
|
||||
if (auto channel = peer->asChannel()) {
|
||||
return !channel->isBroadcast();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
Ui::show(Box<ShareBox>(std::move(copyCallback), std::move(submitCallback), std::move(filterCallback)));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void ShareGameScoreByHash(const QString &hash) {
|
||||
auto key128Size = 0x10;
|
||||
|
||||
|
@ -988,12 +892,12 @@ void ShareGameScoreByHash(const QString &hash) {
|
|||
}
|
||||
|
||||
if (auto item = App::histItemById(channelId, msgId)) {
|
||||
ShareGameScoreFromItem(item);
|
||||
FastShareMessage(item);
|
||||
} else if (App::api()) {
|
||||
auto resolveMessageAndShareScore = [msgId](ChannelData *channel) {
|
||||
App::api()->requestMessageData(channel, msgId, [](ChannelData *channel, MsgId msgId) {
|
||||
if (auto item = App::histItemById(channel, msgId)) {
|
||||
ShareGameScoreFromItem(item);
|
||||
FastShareMessage(item);
|
||||
} else {
|
||||
Ui::show(Box<InformBox>(lang(lng_edit_deleted)));
|
||||
}
|
||||
|
|
|
@ -483,3 +483,8 @@ historyAdminLogCancelSearch: CrossButton {
|
|||
}
|
||||
historyAdminLogSearchTop: 11px;
|
||||
historyAdminLogSearchSlideDuration: 150;
|
||||
|
||||
historyFastShareSize: 31px;
|
||||
historyFastShareLeft: 13px;
|
||||
historyFastShareBottom: 5px;
|
||||
historyFastShareIcon: icon {{ "fast_share", msgServiceFg, point(4px, 3px)}};
|
||||
|
|
|
@ -692,6 +692,14 @@ public:
|
|||
|
||||
virtual void drawInfo(Painter &p, int32 right, int32 bottom, int32 width, bool selected, InfoDisplayType type) const {
|
||||
}
|
||||
virtual ClickHandlerPtr fastShareLink() const {
|
||||
return ClickHandlerPtr();
|
||||
}
|
||||
virtual bool displayFastShare() const {
|
||||
return false;
|
||||
}
|
||||
virtual void drawFastShare(Painter &p, int left, int top, int outerWidth) const {
|
||||
}
|
||||
virtual void setViewsCount(int32 count) {
|
||||
}
|
||||
virtual void setId(MsgId newId);
|
||||
|
|
|
@ -59,6 +59,9 @@ public:
|
|||
virtual bool hasTextForCopy() const {
|
||||
return false;
|
||||
}
|
||||
virtual bool allowsFastShare() const {
|
||||
return false;
|
||||
}
|
||||
virtual void initDimensions() = 0;
|
||||
virtual void updateMessageId() {
|
||||
}
|
||||
|
|
|
@ -453,14 +453,20 @@ void HistoryPhoto::draw(Painter &p, const QRect &r, TextSelection selection, Tim
|
|||
}
|
||||
|
||||
// date
|
||||
if (_caption.isEmpty()) {
|
||||
if (notChild && (_data->uploading() || App::hoveredItem() == _parent)) {
|
||||
int32 fullRight = skipx + width, fullBottom = skipy + height;
|
||||
_parent->drawInfo(p, fullRight, fullBottom, 2 * skipx + width, selected, InfoDisplayOverImage);
|
||||
}
|
||||
} else {
|
||||
if (!_caption.isEmpty()) {
|
||||
p.setPen(outbg ? (selected ? st::historyTextOutFgSelected : st::historyTextOutFg) : (selected ? st::historyTextInFgSelected : st::historyTextInFg));
|
||||
_caption.draw(p, st::msgPadding.left(), skipy + height + st::mediaPadding.bottom() + st::mediaCaptionSkip, captionw, style::al_left, 0, -1, selection);
|
||||
} else if (notChild) {
|
||||
auto fullRight = skipx + width;
|
||||
auto fullBottom = skipy + height;
|
||||
if (_data->uploading() || App::hoveredItem() == _parent) {
|
||||
_parent->drawInfo(p, fullRight, fullBottom, 2 * skipx + width, selected, InfoDisplayOverImage);
|
||||
}
|
||||
if (!bubble && _parent->displayFastShare()) {
|
||||
auto fastShareLeft = (fullRight + st::historyFastShareLeft);
|
||||
auto fastShareTop = (fullBottom - st::historyFastShareBottom - st::historyFastShareSize);
|
||||
_parent->drawFastShare(p, fastShareLeft, fastShareTop, 2 * skipx + width);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -469,7 +475,7 @@ HistoryTextState HistoryPhoto::getState(QPoint point, HistoryStateRequest reques
|
|||
|
||||
if (_width < st::msgPadding.left() + st::msgPadding.right() + 1) return result;
|
||||
int skipx = 0, skipy = 0, width = _width, height = _height;
|
||||
bool bubble = _parent->hasBubble();
|
||||
auto bubble = _parent->hasBubble();
|
||||
|
||||
if (bubble) {
|
||||
skipx = st::mediaPadding.left();
|
||||
|
@ -502,14 +508,20 @@ HistoryTextState HistoryPhoto::getState(QPoint point, HistoryStateRequest reques
|
|||
} else {
|
||||
result.link = _savel;
|
||||
}
|
||||
if (_caption.isEmpty() && _parent->getMedia() == this) {
|
||||
auto fullRight = skipx + width;
|
||||
auto fullBottom = skipy + height;
|
||||
if (_parent->pointInTime(fullRight, fullBottom, point, InfoDisplayOverImage)) {
|
||||
result.cursor = HistoryInDateCursorState;
|
||||
}
|
||||
if (_caption.isEmpty() && _parent->getMedia() == this) {
|
||||
auto fullRight = skipx + width;
|
||||
auto fullBottom = skipy + height;
|
||||
if (_parent->pointInTime(fullRight, fullBottom, point, InfoDisplayOverImage)) {
|
||||
result.cursor = HistoryInDateCursorState;
|
||||
}
|
||||
if (!bubble && _parent->displayFastShare()) {
|
||||
auto fastShareLeft = (fullRight + st::historyFastShareLeft);
|
||||
auto fastShareTop = (fullBottom - st::historyFastShareBottom - st::historyFastShareSize);
|
||||
if (QRect(fastShareLeft, fastShareTop, st::historyFastShareSize, st::historyFastShareSize).contains(point)) {
|
||||
result.link = _parent->fastShareLink();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -830,14 +842,17 @@ void HistoryVideo::draw(Painter &p, const QRect &r, TextSelection selection, Tim
|
|||
p.drawTextLeft(statusX, statusY, _width, _statusText, statusW - 2 * st::msgDateImgPadding.x());
|
||||
|
||||
// date
|
||||
if (_caption.isEmpty()) {
|
||||
if (_parent->getMedia() == this) {
|
||||
int32 fullRight = skipx + width, fullBottom = skipy + height;
|
||||
_parent->drawInfo(p, fullRight, fullBottom, 2 * skipx + width, selected, InfoDisplayOverImage);
|
||||
}
|
||||
} else {
|
||||
if (!_caption.isEmpty()) {
|
||||
p.setPen(outbg ? (selected ? st::historyTextOutFgSelected : st::historyTextOutFg) : (selected ? st::historyTextInFgSelected : st::historyTextInFg));
|
||||
_caption.draw(p, st::msgPadding.left(), skipy + height + st::mediaPadding.bottom() + st::mediaCaptionSkip, captionw, style::al_left, 0, -1, selection);
|
||||
} else if (_parent->getMedia() == this) {
|
||||
auto fullRight = skipx + width, fullBottom = skipy + height;
|
||||
_parent->drawInfo(p, fullRight, fullBottom, 2 * skipx + width, selected, InfoDisplayOverImage);
|
||||
if (!bubble && _parent->displayFastShare()) {
|
||||
auto fastShareLeft = (fullRight + st::historyFastShareLeft);
|
||||
auto fastShareTop = (fullBottom - st::historyFastShareBottom - st::historyFastShareSize);
|
||||
_parent->drawFastShare(p, fastShareLeft, fastShareTop, 2 * skipx + width);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -874,14 +889,20 @@ HistoryTextState HistoryVideo::getState(QPoint point, HistoryStateRequest reques
|
|||
} else {
|
||||
result.link = loaded ? _openl : (_data->loading() ? _cancell : _savel);
|
||||
}
|
||||
if (_caption.isEmpty() && _parent->getMedia() == this) {
|
||||
auto fullRight = skipx + width;
|
||||
auto fullBottom = skipy + height;
|
||||
if (_parent->pointInTime(fullRight, fullBottom, point, InfoDisplayOverImage)) {
|
||||
result.cursor = HistoryInDateCursorState;
|
||||
}
|
||||
if (_caption.isEmpty() && _parent->getMedia() == this) {
|
||||
auto fullRight = skipx + width;
|
||||
auto fullBottom = skipy + height;
|
||||
if (_parent->pointInTime(fullRight, fullBottom, point, InfoDisplayOverImage)) {
|
||||
result.cursor = HistoryInDateCursorState;
|
||||
}
|
||||
if (!bubble && _parent->displayFastShare()) {
|
||||
auto fastShareLeft = (fullRight + st::historyFastShareLeft);
|
||||
auto fastShareTop = (fullBottom - st::historyFastShareBottom - st::historyFastShareSize);
|
||||
if (QRect(fastShareLeft, fastShareTop, st::historyFastShareSize, st::historyFastShareSize).contains(point)) {
|
||||
result.link = _parent->fastShareLink();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -2160,30 +2181,40 @@ void HistoryGif::draw(Painter &p, const QRect &r, TextSelection selection, TimeM
|
|||
}
|
||||
}
|
||||
}
|
||||
if (!_caption.isEmpty()) {
|
||||
if (!isRound && !_caption.isEmpty()) {
|
||||
p.setPen(outbg ? (selected ? st::historyTextOutFgSelected : st::historyTextOutFg) : (selected ? st::historyTextInFgSelected : st::historyTextInFg));
|
||||
_caption.draw(p, st::msgPadding.left(), skipy + height + st::mediaPadding.bottom() + st::mediaCaptionSkip, captionw, style::al_left, 0, -1, selection);
|
||||
} else if (!isChildMedia && (isRound || _data->uploading() || App::hoveredItem() == _parent)) {
|
||||
} else if (!isChildMedia) {
|
||||
auto fullRight = skipx + usex + usew;
|
||||
auto fullBottom = skipy + height;
|
||||
auto maxRight = _parent->history()->width - st::msgMargin.left();
|
||||
if (_parent->history()->canHaveFromPhotos()) {
|
||||
maxRight -= st::msgMargin.right();
|
||||
} else {
|
||||
maxRight -= st::msgMargin.left();
|
||||
}
|
||||
if (isRound && !outbg) {
|
||||
auto infoWidth = _parent->infoWidth();
|
||||
|
||||
// This is just some arbitrary point,
|
||||
// the main idea is to make info left aligned here.
|
||||
fullRight += infoWidth - st::normalFont->height;
|
||||
|
||||
auto maxRight = _parent->history()->width - st::msgMargin.left();
|
||||
if (_parent->history()->canHaveFromPhotos()) {
|
||||
maxRight -= st::msgMargin.right();
|
||||
} else {
|
||||
maxRight -= st::msgMargin.left();
|
||||
}
|
||||
if (fullRight > maxRight) {
|
||||
fullRight = maxRight;
|
||||
}
|
||||
}
|
||||
_parent->drawInfo(p, fullRight, fullBottom, 2 * skipx + width, selected, isRound ? InfoDisplayOverBackground : InfoDisplayOverImage);
|
||||
if (isRound || _data->uploading() || App::hoveredItem() == _parent) {
|
||||
_parent->drawInfo(p, fullRight, fullBottom, 2 * skipx + width, selected, isRound ? InfoDisplayOverBackground : InfoDisplayOverImage);
|
||||
}
|
||||
if (!bubble && _parent->displayFastShare()) {
|
||||
auto fastShareLeft = (fullRight + st::historyFastShareLeft);
|
||||
auto fastShareTop = (fullBottom - st::historyFastShareBottom - st::historyFastShareSize);
|
||||
if (fastShareLeft + st::historyFastShareSize > maxRight) {
|
||||
fastShareLeft = (fullRight - st::historyFastShareSize - st::msgDateImgDelta);
|
||||
fastShareTop -= (st::msgDateImgDelta + st::msgDateImgPadding.y() + st::msgDateFont->height + st::msgDateImgPadding.y());
|
||||
}
|
||||
_parent->drawFastShare(p, fastShareLeft, fastShareTop, 2 * skipx + width);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2212,8 +2243,9 @@ HistoryTextState HistoryGif::getState(QPoint point, HistoryStateRequest request)
|
|||
width -= st::mediaPadding.left() + st::mediaPadding.right();
|
||||
height -= skipy + st::mediaPadding.bottom();
|
||||
}
|
||||
auto out = _parent->out(), isPost = _parent->isPost();
|
||||
bool out = _parent->out(), isPost = _parent->isPost(), outbg = out && !isPost;
|
||||
auto isChildMedia = (_parent->getMedia() != this);
|
||||
auto isRound = _data->isRoundVideo();
|
||||
auto usew = width, usex = 0;
|
||||
auto separateRoundVideo = isSeparateRoundVideo();
|
||||
auto via = separateRoundVideo ? _parent->Get<HistoryMessageVia>() : nullptr;
|
||||
|
@ -2290,14 +2322,42 @@ HistoryTextState HistoryGif::getState(QPoint point, HistoryStateRequest request)
|
|||
} else {
|
||||
result.link = _openInMediaviewLink;
|
||||
}
|
||||
}
|
||||
if (isRound || _caption.isEmpty()) {
|
||||
auto fullRight = usex + skipx + usew;
|
||||
auto fullBottom = skipy + height;
|
||||
auto maxRight = _parent->history()->width - st::msgMargin.left();
|
||||
if (_parent->history()->canHaveFromPhotos()) {
|
||||
maxRight -= st::msgMargin.right();
|
||||
} else {
|
||||
maxRight -= st::msgMargin.left();
|
||||
}
|
||||
if (isRound && !outbg) {
|
||||
auto infoWidth = _parent->infoWidth();
|
||||
|
||||
// This is just some arbitrary point,
|
||||
// the main idea is to make info left aligned here.
|
||||
fullRight += infoWidth - st::normalFont->height;
|
||||
if (fullRight > maxRight) {
|
||||
fullRight = maxRight;
|
||||
}
|
||||
}
|
||||
if (!isChildMedia) {
|
||||
auto fullRight = usex + skipx + usew;
|
||||
auto fullBottom = skipy + height;
|
||||
if (_parent->pointInTime(fullRight, fullBottom, point, InfoDisplayOverImage)) {
|
||||
if (_parent->pointInTime(fullRight, fullBottom, point, isRound ? InfoDisplayOverBackground : InfoDisplayOverImage)) {
|
||||
result.cursor = HistoryInDateCursorState;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
if (!bubble && _parent->displayFastShare()) {
|
||||
auto fastShareLeft = (fullRight + st::historyFastShareLeft);
|
||||
auto fastShareTop = (fullBottom - st::historyFastShareBottom - st::historyFastShareSize);
|
||||
if (fastShareLeft + st::historyFastShareSize > maxRight) {
|
||||
fastShareLeft = (fullRight - st::historyFastShareSize - st::msgDateImgDelta);
|
||||
fastShareTop -= st::msgDateImgDelta + st::msgDateImgPadding.y() + st::msgDateFont->height + st::msgDateImgPadding.y();
|
||||
}
|
||||
if (QRect(fastShareLeft, fastShareTop, st::historyFastShareSize, st::historyFastShareSize).contains(point)) {
|
||||
result.link = _parent->fastShareLink();
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -2637,8 +2697,9 @@ void HistorySticker::draw(Painter &p, const QRect &r, TextSelection selection, T
|
|||
}
|
||||
|
||||
if (!childmedia) {
|
||||
_parent->drawInfo(p, usex + usew, _height, usex * 2 + usew, selected, InfoDisplayOverBackground);
|
||||
|
||||
auto fullRight = usex + usew;
|
||||
auto fullBottom = _height;
|
||||
_parent->drawInfo(p, fullRight, fullBottom, usex * 2 + usew, selected, InfoDisplayOverBackground);
|
||||
if (via || reply) {
|
||||
int rectw = _width - usew - st::msgReplyPadding.left();
|
||||
int recth = st::msgReplyPadding.top() + st::msgReplyPadding.bottom();
|
||||
|
@ -2673,6 +2734,11 @@ void HistorySticker::draw(Painter &p, const QRect &r, TextSelection selection, T
|
|||
reply->paint(p, _parent, rectx, recty, rectw, flags);
|
||||
}
|
||||
}
|
||||
if (_parent->displayFastShare()) {
|
||||
auto fastShareLeft = (fullRight + st::historyFastShareLeft);
|
||||
auto fastShareTop = (fullBottom - st::historyFastShareBottom - st::historyFastShareSize);
|
||||
_parent->drawFastShare(p, fastShareLeft, fastShareTop, 2 * usex + usew);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2728,9 +2794,18 @@ HistoryTextState HistorySticker::getState(QPoint point, HistoryStateRequest requ
|
|||
}
|
||||
}
|
||||
if (_parent->getMedia() == this) {
|
||||
if (_parent->pointInTime(usex + usew, _height, point, InfoDisplayOverImage)) {
|
||||
auto fullRight = usex + usew;
|
||||
auto fullBottom = _height;
|
||||
if (_parent->pointInTime(fullRight, fullBottom, point, InfoDisplayOverImage)) {
|
||||
result.cursor = HistoryInDateCursorState;
|
||||
}
|
||||
if (_parent->displayFastShare()) {
|
||||
auto fastShareLeft = (fullRight + st::historyFastShareLeft);
|
||||
auto fastShareTop = (fullBottom - st::historyFastShareBottom - st::historyFastShareSize);
|
||||
if (QRect(fastShareLeft, fastShareTop, st::historyFastShareSize, st::historyFastShareSize).contains(point)) {
|
||||
result.link = _parent->fastShareLink();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto pixLeft = usex + (usew - _pixw) / 2;
|
||||
|
@ -4614,8 +4689,14 @@ void HistoryLocation::draw(Painter &p, const QRect &r, TextSelection selection,
|
|||
}
|
||||
|
||||
if (_parent->getMedia() == this) {
|
||||
int32 fullRight = skipx + width, fullBottom = _height - (skipx ? st::mediaPadding.bottom() : 0);
|
||||
auto fullRight = skipx + width;
|
||||
auto fullBottom = _height - (skipx ? st::mediaPadding.bottom() : 0);
|
||||
_parent->drawInfo(p, fullRight, fullBottom, skipx * 2 + width, selected, InfoDisplayOverImage);
|
||||
if (!bubble && _parent->displayFastShare()) {
|
||||
auto fastShareLeft = (fullRight + st::historyFastShareLeft);
|
||||
auto fastShareTop = (fullBottom - st::historyFastShareBottom - st::historyFastShareSize);
|
||||
_parent->drawFastShare(p, fastShareLeft, fastShareTop, 2 * skipx + width);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4666,12 +4747,20 @@ HistoryTextState HistoryLocation::getState(QPoint point, HistoryStateRequest req
|
|||
}
|
||||
if (QRect(skipx, skipy, width, height).contains(point) && _data) {
|
||||
result.link = _link;
|
||||
|
||||
}
|
||||
if (_parent->getMedia() == this) {
|
||||
auto fullRight = skipx + width;
|
||||
auto fullBottom = _height - (skipx ? st::mediaPadding.bottom() : 0);
|
||||
if (_parent->pointInTime(fullRight, fullBottom, point, InfoDisplayOverImage)) {
|
||||
result.cursor = HistoryInDateCursorState;
|
||||
}
|
||||
if (!bubble && _parent->displayFastShare()) {
|
||||
auto fastShareLeft = (fullRight + st::historyFastShareLeft);
|
||||
auto fastShareTop = (fullBottom - st::historyFastShareBottom - st::historyFastShareSize);
|
||||
if (QRect(fastShareLeft, fastShareTop, st::historyFastShareSize, st::historyFastShareSize).contains(point)) {
|
||||
result.link = _parent->fastShareLink();
|
||||
}
|
||||
}
|
||||
}
|
||||
result.symbol += symbolAdd;
|
||||
return result;
|
||||
|
|
|
@ -45,6 +45,10 @@ public:
|
|||
void clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active) override;
|
||||
void clickHandlerPressedChanged(const ClickHandlerPtr &p, bool pressed) override;
|
||||
|
||||
bool allowsFastShare() const override {
|
||||
return true;
|
||||
}
|
||||
|
||||
~HistoryFileMedia();
|
||||
|
||||
protected:
|
||||
|
@ -835,6 +839,9 @@ public:
|
|||
bool customInfoLayout() const override {
|
||||
return false;
|
||||
}
|
||||
bool allowsFastShare() const override {
|
||||
return true;
|
||||
}
|
||||
|
||||
HistoryMedia *attach() const {
|
||||
return _attach.get();
|
||||
|
@ -946,6 +953,9 @@ public:
|
|||
bool customInfoLayout() const override {
|
||||
return false;
|
||||
}
|
||||
bool allowsFastShare() const override {
|
||||
return true;
|
||||
}
|
||||
|
||||
HistoryMedia *attach() const {
|
||||
return _attach.get();
|
||||
|
|
|
@ -29,6 +29,10 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
#include "history/history_media_types.h"
|
||||
#include "history/history_service.h"
|
||||
#include "auth_session.h"
|
||||
#include "boxes/share_box.h"
|
||||
#include "boxes/confirm_box.h"
|
||||
#include "ui/toast/toast.h"
|
||||
#include "messenger.h"
|
||||
#include "styles/style_dialogs.h"
|
||||
#include "styles/style_widgets.h"
|
||||
#include "styles/style_history.h"
|
||||
|
@ -105,8 +109,178 @@ MTPDmessage::Flags NewForwardedFlags(gsl::not_null<PeerData*> peer, int32 from,
|
|||
return result;
|
||||
}
|
||||
|
||||
bool HasMediaItems(const SelectedItemSet &items) {
|
||||
for_const (auto item, items) {
|
||||
if (auto media = item->getMedia()) {
|
||||
switch (media->type()) {
|
||||
case MediaTypePhoto:
|
||||
case MediaTypeVideo:
|
||||
case MediaTypeFile:
|
||||
case MediaTypeMusicFile:
|
||||
case MediaTypeVoiceFile: return true;
|
||||
case MediaTypeGif: return media->getDocument()->isRoundVideo();
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HasStickerItems(const SelectedItemSet &items) {
|
||||
for_const (auto item, items) {
|
||||
if (auto media = item->getMedia()) {
|
||||
switch (media->type()) {
|
||||
case MediaTypeSticker: return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HasGifItems(const SelectedItemSet &items) {
|
||||
for_const (auto item, items) {
|
||||
if (auto media = item->getMedia()) {
|
||||
switch (media->type()) {
|
||||
case MediaTypeGif: return !media->getDocument()->isRoundVideo();
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HasGameItems(const SelectedItemSet &items) {
|
||||
for_const (auto item, items) {
|
||||
if (auto media = item->getMedia()) {
|
||||
switch (media->type()) {
|
||||
case MediaTypeGame: return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HasInlineItems(const SelectedItemSet &items) {
|
||||
for_const (auto item, items) {
|
||||
if (item->viaBot()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void FastShareMessage(gsl::not_null<HistoryItem*> item) {
|
||||
struct ShareData {
|
||||
ShareData(const FullMsgId &msgId) : msgId(msgId) {
|
||||
}
|
||||
FullMsgId msgId;
|
||||
OrderedSet<mtpRequestId> requests;
|
||||
};
|
||||
auto data = MakeShared<ShareData>(item->fullId());
|
||||
|
||||
auto canCopyLink = item->hasDirectLink();
|
||||
if (!canCopyLink) {
|
||||
if (auto bot = item->getMessageBot()) {
|
||||
if (auto media = item->getMedia()) {
|
||||
canCopyLink = (media->type() == MediaTypeGame);
|
||||
}
|
||||
}
|
||||
}
|
||||
auto copyCallback = [data]() {
|
||||
if (auto main = App::main()) {
|
||||
if (auto item = App::histItemById(data->msgId)) {
|
||||
if (item->hasDirectLink()) {
|
||||
QApplication::clipboard()->setText(item->directLink());
|
||||
|
||||
Ui::Toast::Show(lang(lng_channel_public_link_copied));
|
||||
} else if (auto bot = item->getMessageBot()) {
|
||||
if (auto media = item->getMedia()) {
|
||||
if (media->type() == MediaTypeGame) {
|
||||
auto shortName = static_cast<HistoryGame*>(media)->game()->shortName;
|
||||
|
||||
QApplication::clipboard()->setText(Messenger::Instance().createInternalLinkFull(bot->username + qsl("?game=") + shortName));
|
||||
|
||||
Ui::Toast::Show(lang(lng_share_game_link_copied));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
auto submitCallback = [data](const QVector<PeerData*> &result) {
|
||||
if (!data->requests.empty()) {
|
||||
return; // Share clicked already.
|
||||
}
|
||||
auto item = App::histItemById(data->msgId);
|
||||
if (!item || result.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto items = SelectedItemSet();
|
||||
auto restrictedSomewhere = false;
|
||||
auto restrictedEverywhere = true;
|
||||
auto firstError = QString();
|
||||
items.insert(item->id, item);
|
||||
for_const (auto peer, result) {
|
||||
auto error = GetErrorTextForForward(peer, items);
|
||||
if (!error.isEmpty()) {
|
||||
if (firstError.isEmpty()) {
|
||||
firstError = error;
|
||||
}
|
||||
restrictedSomewhere = true;
|
||||
continue;
|
||||
}
|
||||
restrictedEverywhere = false;
|
||||
}
|
||||
if (restrictedEverywhere) {
|
||||
Ui::show(Box<InformBox>(firstError), KeepOtherLayers);
|
||||
return;
|
||||
}
|
||||
|
||||
auto doneCallback = [data](const MTPUpdates &updates, mtpRequestId requestId) {
|
||||
if (auto main = App::main()) {
|
||||
main->sentUpdatesReceived(updates);
|
||||
}
|
||||
data->requests.remove(requestId);
|
||||
if (data->requests.empty()) {
|
||||
Ui::Toast::Show(lang(lng_share_done));
|
||||
Ui::hideLayer();
|
||||
}
|
||||
};
|
||||
|
||||
auto sendFlags = MTPmessages_ForwardMessages::Flag::f_with_my_score;
|
||||
MTPVector<MTPint> msgIds = MTP_vector<MTPint>(1, MTP_int(data->msgId.msg));
|
||||
if (auto main = App::main()) {
|
||||
for_const (auto peer, result) {
|
||||
if (!GetErrorTextForForward(peer, items).isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
MTPVector<MTPlong> random = MTP_vector<MTPlong>(1, rand_value<MTPlong>());
|
||||
auto request = MTPmessages_ForwardMessages(MTP_flags(sendFlags), item->history()->peer->input, msgIds, random, peer->input);
|
||||
auto callback = doneCallback;
|
||||
auto requestId = MTP::send(request, rpcDone(std::move(callback)));
|
||||
data->requests.insert(requestId);
|
||||
}
|
||||
}
|
||||
};
|
||||
auto filterCallback = [](PeerData *peer) {
|
||||
if (peer->canWrite()) {
|
||||
if (auto channel = peer->asChannel()) {
|
||||
return !channel->isBroadcast();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
auto copyLinkCallback = canCopyLink ? base::lambda<void()>(std::move(copyCallback)) : base::lambda<void()>();
|
||||
Ui::show(Box<ShareBox>(std::move(copyLinkCallback), std::move(submitCallback), std::move(filterCallback)));
|
||||
}
|
||||
|
||||
void HistoryInitMessages() {
|
||||
initTextOptions();
|
||||
}
|
||||
|
||||
base::lambda<void(ChannelData*, MsgId)> HistoryDependentItemCallback(const FullMsgId &msgId) {
|
||||
return [dependent = msgId](ChannelData *channel, MsgId msgId) {
|
||||
if (auto item = App::histItemById(dependent)) {
|
||||
|
@ -126,8 +300,25 @@ MTPDmessage::Flags NewMessageFlags(gsl::not_null<PeerData*> peer) {
|
|||
return result;
|
||||
}
|
||||
|
||||
void HistoryInitMessages() {
|
||||
initTextOptions();
|
||||
QString GetErrorTextForForward(gsl::not_null<PeerData*> peer, const SelectedItemSet &items) {
|
||||
if (!peer->canWrite()) {
|
||||
return lang(lng_forward_cant);
|
||||
}
|
||||
|
||||
if (auto megagroup = peer->asMegagroup()) {
|
||||
if (megagroup->restrictedRights().is_send_media() && HasMediaItems(items)) {
|
||||
return lang(lng_restricted_send_media);
|
||||
} else if (megagroup->restrictedRights().is_send_stickers() && HasStickerItems(items)) {
|
||||
return lang(lng_restricted_send_stickers);
|
||||
} else if (megagroup->restrictedRights().is_send_gifs() && HasGifItems(items)) {
|
||||
return lang(lng_restricted_send_gifs);
|
||||
} else if (megagroup->restrictedRights().is_send_games() && HasGameItems(items)) {
|
||||
return lang(lng_restricted_send_inline);
|
||||
} else if (megagroup->restrictedRights().is_send_inline() && HasInlineItems(items)) {
|
||||
return lang(lng_restricted_send_inline);
|
||||
}
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
void HistoryMessageVia::create(int32 userId) {
|
||||
|
@ -609,6 +800,17 @@ bool HistoryMessage::uploading() const {
|
|||
return _media && _media->uploading();
|
||||
}
|
||||
|
||||
bool HistoryMessage::displayFastShare() const {
|
||||
if (_history->peer->isChannel()) {
|
||||
return !_history->peer->isMegagroup();
|
||||
} else if (auto user = _history->peer->asUser()) {
|
||||
if (user->botInfo && !out()) {
|
||||
return _media && _media->allowsFastShare();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void HistoryMessage::createComponents(const CreateConfig &config) {
|
||||
uint64 mask = 0;
|
||||
if (config.replyTo) {
|
||||
|
@ -1476,6 +1678,11 @@ void HistoryMessage::draw(Painter &p, QRect clip, TextSelection selection, TimeM
|
|||
if (needDrawInfo) {
|
||||
HistoryMessage::drawInfo(p, g.left() + g.width(), g.top() + g.height(), 2 * g.left() + g.width(), selected, InfoDisplayDefault);
|
||||
}
|
||||
if (displayFastShare()) {
|
||||
auto fastShareLeft = g.left() + g.width() + st::historyFastShareLeft;
|
||||
auto fastShareTop = g.top() + g.height() - st::historyFastShareBottom - st::historyFastShareSize;
|
||||
drawFastShare(p, fastShareLeft, fastShareTop, width());
|
||||
}
|
||||
} else if (_media) {
|
||||
p.translate(g.topLeft());
|
||||
_media->draw(p, clip.translated(-g.topLeft()), skipTextSelection(selection), ms);
|
||||
|
@ -1490,6 +1697,17 @@ void HistoryMessage::draw(Painter &p, QRect clip, TextSelection selection, TimeM
|
|||
}
|
||||
}
|
||||
|
||||
void HistoryMessage::drawFastShare(Painter &p, int left, int top, int outerWidth) const {
|
||||
{
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setBrush(st::msgServiceBg);
|
||||
|
||||
PainterHighQualityEnabler hq(p);
|
||||
p.drawEllipse(rtlrect(left, top, st::historyFastShareSize, st::historyFastShareSize, outerWidth));
|
||||
}
|
||||
st::historyFastShareIcon.paint(p, left, top, outerWidth);
|
||||
}
|
||||
|
||||
void HistoryMessage::paintFromName(Painter &p, QRect &trect, bool selected) const {
|
||||
if (displayFromName()) {
|
||||
p.setFont(st::msgNameFont);
|
||||
|
@ -1791,6 +2009,13 @@ HistoryTextState HistoryMessage::getState(QPoint point, HistoryStateRequest requ
|
|||
result.cursor = HistoryInDateCursorState;
|
||||
}
|
||||
}
|
||||
if (displayFastShare()) {
|
||||
auto fastShareLeft = g.left() + g.width() + st::historyFastShareLeft;
|
||||
auto fastShareTop = g.top() + g.height() - st::historyFastShareBottom - st::historyFastShareSize;
|
||||
if (QRect(fastShareLeft, fastShareTop, st::historyFastShareSize, st::historyFastShareSize).contains(point)) {
|
||||
result.link = fastShareLink();
|
||||
}
|
||||
}
|
||||
} else if (_media) {
|
||||
result = _media->getState(point - g.topLeft(), request);
|
||||
result.symbol += _text.length();
|
||||
|
@ -1807,6 +2032,17 @@ HistoryTextState HistoryMessage::getState(QPoint point, HistoryStateRequest requ
|
|||
return result;
|
||||
}
|
||||
|
||||
ClickHandlerPtr HistoryMessage::fastShareLink() const {
|
||||
if (!_fastShareLink) {
|
||||
_fastShareLink = MakeShared<LambdaClickHandler>([id = fullId()] {
|
||||
if (auto item = App::histItemById(id)) {
|
||||
FastShareMessage(item->toHistoryMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
return _fastShareLink;
|
||||
}
|
||||
|
||||
// Forward to _media.
|
||||
void HistoryMessage::updatePressed(QPoint point) {
|
||||
if (!_media) return;
|
||||
|
|
|
@ -23,6 +23,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
void HistoryInitMessages();
|
||||
base::lambda<void(ChannelData*, MsgId)> HistoryDependentItemCallback(const FullMsgId &msgId);
|
||||
MTPDmessage::Flags NewMessageFlags(gsl::not_null<PeerData*> peer);
|
||||
QString GetErrorTextForForward(gsl::not_null<PeerData*> peer, const SelectedItemSet &items);
|
||||
void FastShareMessage(gsl::not_null<HistoryItem*> item);
|
||||
|
||||
class HistoryMessage : public HistoryItem, private HistoryItemInstantiated<HistoryMessage> {
|
||||
public:
|
||||
|
@ -67,11 +69,14 @@ public:
|
|||
}
|
||||
bool displayEditedBadge(bool hasViaBotOrInlineMarkup) const;
|
||||
bool uploading() const;
|
||||
bool displayFastShare() const override;
|
||||
|
||||
void drawInfo(Painter &p, int32 right, int32 bottom, int32 width, bool selected, InfoDisplayType type) const override;
|
||||
void drawFastShare(Painter &p, int left, int top, int outerWidth) const override;
|
||||
void setViewsCount(int32 count) override;
|
||||
void setId(MsgId newId) override;
|
||||
void draw(Painter &p, QRect clip, TextSelection selection, TimeMs ms) const override;
|
||||
ClickHandlerPtr fastShareLink() const override;
|
||||
|
||||
void dependencyItemRemoved(HistoryItem *dependency) override;
|
||||
|
||||
|
@ -181,6 +186,8 @@ private:
|
|||
QString _timeText;
|
||||
int _timeWidth = 0;
|
||||
|
||||
mutable ClickHandlerPtr _fastShareLink;
|
||||
|
||||
struct CreateConfig {
|
||||
MsgId replyTo = 0;
|
||||
UserId viaBotId = 0;
|
||||
|
|
|
@ -92,64 +92,6 @@ MTPMessagesFilter TypeToMediaFilter(MediaOverviewType &type) {
|
|||
}
|
||||
}
|
||||
|
||||
bool HasMediaItems(const SelectedItemSet &items) {
|
||||
for_const (auto item, items) {
|
||||
if (auto media = item->getMedia()) {
|
||||
switch (media->type()) {
|
||||
case MediaTypePhoto:
|
||||
case MediaTypeVideo:
|
||||
case MediaTypeFile:
|
||||
case MediaTypeMusicFile:
|
||||
case MediaTypeVoiceFile: return true;
|
||||
case MediaTypeGif: return media->getDocument()->isRoundVideo();
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HasStickerItems(const SelectedItemSet &items) {
|
||||
for_const (auto item, items) {
|
||||
if (auto media = item->getMedia()) {
|
||||
switch (media->type()) {
|
||||
case MediaTypeSticker: return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HasGifItems(const SelectedItemSet &items) {
|
||||
for_const (auto item, items) {
|
||||
if (auto media = item->getMedia()) {
|
||||
switch (media->type()) {
|
||||
case MediaTypeGif: return !media->getDocument()->isRoundVideo();
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HasGameItems(const SelectedItemSet &items) {
|
||||
for_const (auto item, items) {
|
||||
if (auto media = item->getMedia()) {
|
||||
switch (media->type()) {
|
||||
case MediaTypeGame: return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HasInlineItems(const SelectedItemSet &items) {
|
||||
for_const (auto item, items) {
|
||||
if (item->viaBot()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
StackItemSection::StackItemSection(std::unique_ptr<Window::SectionMemento> &&memento) : StackItem(nullptr)
|
||||
|
@ -596,26 +538,10 @@ bool MainWidget::setForwardDraft(PeerId peerId, ForwardWhatMessages what) {
|
|||
bool MainWidget::setForwardDraft(PeerId peerId, const SelectedItemSet &items) {
|
||||
Expects(peerId != 0);
|
||||
auto peer = App::peer(peerId);
|
||||
auto finishWithError = [this](const QString &error) {
|
||||
auto error = GetErrorTextForForward(peer, items);
|
||||
if (!error.isEmpty()) {
|
||||
Ui::show(Box<InformBox>(error));
|
||||
return false;
|
||||
};
|
||||
if (!peer->canWrite()) {
|
||||
return finishWithError(lang(lng_forward_cant));
|
||||
}
|
||||
|
||||
if (auto megagroup = peer->asMegagroup()) {
|
||||
if (megagroup->restrictedRights().is_send_media() && HasMediaItems(items)) {
|
||||
return finishWithError(lang(lng_restricted_send_media));
|
||||
} else if (megagroup->restrictedRights().is_send_stickers() && HasStickerItems(items)) {
|
||||
return finishWithError(lang(lng_restricted_send_stickers));
|
||||
} else if (megagroup->restrictedRights().is_send_gifs() && HasGifItems(items)) {
|
||||
return finishWithError(lang(lng_restricted_send_gifs));
|
||||
} else if (megagroup->restrictedRights().is_send_games() && HasGameItems(items)) {
|
||||
return finishWithError(lang(lng_restricted_send_inline));
|
||||
} else if (megagroup->restrictedRights().is_send_inline() && HasInlineItems(items)) {
|
||||
return finishWithError(lang(lng_restricted_send_inline));
|
||||
}
|
||||
}
|
||||
|
||||
App::history(peer)->setForwardDraft(items);
|
||||
|
|
|
@ -35,7 +35,17 @@ NeverFreedPointer<QMap<QObject*, Manager*>> _managers;
|
|||
|
||||
Manager::Manager(QWidget *parent) : QObject(parent) {
|
||||
connect(&_hideTimer, SIGNAL(timeout()), this, SLOT(onHideTimeout()));
|
||||
connect(parent, SIGNAL(resized()), this, SLOT(onParentResized()));
|
||||
}
|
||||
|
||||
bool Manager::eventFilter(QObject *o, QEvent *e) {
|
||||
if (e->type() == QEvent::Resize) {
|
||||
for (auto i = _toastByWidget.cbegin(), e = _toastByWidget.cend(); i != e; ++i) {
|
||||
if (i.key()->parentWidget() == o) {
|
||||
i.key()->onParentResized();
|
||||
}
|
||||
}
|
||||
}
|
||||
return QObject::eventFilter(o, e);
|
||||
}
|
||||
|
||||
Manager *Manager::instance(QWidget *parent) {
|
||||
|
@ -58,7 +68,23 @@ void Manager::addToast(std::unique_ptr<Instance> &&toast) {
|
|||
|
||||
_toastByWidget.insert(widget, t);
|
||||
connect(widget, SIGNAL(destroyed(QObject*)), this, SLOT(onToastWidgetDestroyed(QObject*)));
|
||||
connect(widget->parentWidget(), SIGNAL(resized(QSize)), this, SLOT(onToastWidgetParentResized()), Qt::UniqueConnection);
|
||||
if (auto parent = widget->parentWidget()) {
|
||||
auto found = false;
|
||||
for (auto i = _toastParents.begin(); i != _toastParents.cend();) {
|
||||
if (*i == parent) {
|
||||
found = true;
|
||||
break;
|
||||
} else if (!*i) {
|
||||
i = _toastParents.erase(i);
|
||||
} else {
|
||||
++i;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
_toastParents.insert(parent);
|
||||
parent->installEventFilter(this);
|
||||
}
|
||||
}
|
||||
|
||||
auto oldHideNearestMs = _toastByHideTime.isEmpty() ? 0LL : _toastByHideTime.firstKey();
|
||||
_toastByHideTime.insert(t->_hideAtMs, t);
|
||||
|
@ -96,17 +122,6 @@ void Manager::onToastWidgetDestroyed(QObject *widget) {
|
|||
}
|
||||
}
|
||||
|
||||
void Manager::onToastWidgetParentResized() {
|
||||
auto resizedWidget = QObject::sender();
|
||||
if (!resizedWidget) return;
|
||||
|
||||
for (auto i = _toastByWidget.cbegin(), e = _toastByWidget.cend(); i != e; ++i) {
|
||||
if (i.key()->parentWidget() == resizedWidget) {
|
||||
i.key()->onParentResized();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Manager::startNextHideTimer() {
|
||||
if (_toastByHideTime.isEmpty()) return;
|
||||
|
||||
|
|
|
@ -41,10 +41,12 @@ public:
|
|||
|
||||
~Manager();
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *o, QEvent *e);
|
||||
|
||||
private slots:
|
||||
void onHideTimeout();
|
||||
void onToastWidgetDestroyed(QObject *widget);
|
||||
void onToastWidgetParentResized();
|
||||
|
||||
private:
|
||||
Manager(QWidget *parent);
|
||||
|
@ -56,6 +58,7 @@ private:
|
|||
QMultiMap<TimeMs, Instance*> _toastByHideTime;
|
||||
QMap<Widget*, Instance*> _toastByWidget;
|
||||
QList<Instance*> _toasts;
|
||||
OrderedSet<QPointer<QWidget>> _toastParents;
|
||||
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue