Fixes in floating dates with migrated histories.

All service messages are now not multiline (including pinned).
Confirmation for profile photo deleting will be added (not enabled).
Copy-by-selection should be supported in Linux version now.
Drafts that contain only reply-to-id (without text) support added.
This commit is contained in:
John Preston 2016-06-14 19:26:41 +03:00
parent 044e9221e8
commit 38c2915533
20 changed files with 182 additions and 120 deletions

View File

@ -880,6 +880,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
"lng_selected_upload_stop" = "Stop";
"lng_selected_delete_sure_this" = "Do you want to delete this message?";
"lng_selected_delete_sure" = "Do you want to delete {count:_not_used_|# message|# messages}?";
"lng_delete_photo_sure" = "Do you want to delete this photo?";
"lng_box_delete" = "Delete";
"lng_box_leave" = "Leave";

View File

@ -84,7 +84,12 @@ namespace {
typedef QMap<uint64, QPair<PeerId, QString> > SentData;
SentData sentData;
HistoryItem *hoveredItem = 0, *pressedItem = 0, *hoveredLinkItem = 0, *pressedLinkItem = 0, *contextItem = 0, *mousedItem = 0;
HistoryItem *hoveredItem = nullptr,
*pressedItem = nullptr,
*hoveredLinkItem = nullptr,
*pressedLinkItem = nullptr,
*contextItem = nullptr,
*mousedItem = nullptr;
QPixmap *emoji = 0, *emojiLarge = 0;
style::font monofont;
@ -1938,7 +1943,7 @@ namespace {
delete toDelete[i];
}
::hoveredItem = ::pressedItem = ::hoveredLinkItem = ::pressedLinkItem = ::contextItem = 0;
clearMousedItems();
}
void historyClearItems() {
@ -2213,6 +2218,15 @@ namespace {
return ::mousedItem;
}
void clearMousedItems() {
hoveredItem(nullptr);
pressedItem(nullptr);
hoveredLinkItem(nullptr);
pressedLinkItem(nullptr);
contextItem(nullptr);
mousedItem(nullptr);
}
const style::font &monofont() {
return ::monofont;
}

View File

@ -205,6 +205,7 @@ namespace App {
HistoryItem *contextItem();
void mousedItem(HistoryItem *item);
HistoryItem *mousedItem();
void clearMousedItems();
const style::font &monofont();
const QPixmap &sprite();

View File

@ -59,7 +59,7 @@ inline bool draftStringIsEmpty(const QString &text) {
}
inline bool draftIsNull(Draft *draft) {
return !draft || draftStringIsEmpty(draft->textWithTags.text);
return !draft || (draftStringIsEmpty(draft->textWithTags.text) && !draft->msgId);
}
inline bool draftsAreEqual(Draft *a, Draft *b) {

View File

@ -44,7 +44,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
namespace {
TextParseOptions _historySrvOptions = {
TextParseLinks | TextParseMentions | TextParseHashtags | TextParseMultiline | TextParseRichText, // flags
TextParseLinks | TextParseMentions | TextParseHashtags/* | TextParseMultiline*/ | TextParseRichText, // flags
0, // maxw
0, // maxh
Qt::LayoutDirectionAuto, // lang-dependent

View File

@ -171,7 +171,10 @@ namespace {
template <typename Method>
void HistoryInner::enumerateItemsInHistory(History *history, int historytop, Method method) {
// no displayed messages in this history
if (historytop < 0 || history->isEmpty() || _visibleAreaBottom <= historytop) {
if (historytop < 0 || history->isEmpty()) {
return;
}
if (_visibleAreaBottom <= historytop || historytop + history->height <= _visibleAreaTop) {
return;
}
@ -262,12 +265,8 @@ void HistoryInner::enumerateUserpics(Method method) {
return true;
};
auto movedToMigratedHistoryCallback = [&lowestAttachedItemBottom]() {
// reset the found bottom of the pack when moved from _history to _migrated enumeration
lowestAttachedItemBottom = -1;
};
enumerateItems(userpicCallback, movedToMigratedHistoryCallback);
enumerateItems(userpicCallback);
}
template <typename Method>
@ -322,12 +321,8 @@ void HistoryInner::enumerateDates(Method method) {
return true;
};
auto movedToMigratedHistoryCallback = [&lowestInOneDayItemBottom]() {
// reset the found bottom of the pack when moved from _history to _migrated enumeration
lowestInOneDayItemBottom = -1;
};
enumerateItems(dateCallback, movedToMigratedHistoryCallback);
enumerateItems(dateCallback);
}
void HistoryInner::paintEvent(QPaintEvent *e) {
@ -486,27 +481,42 @@ void HistoryInner::paintEvent(QPaintEvent *e) {
return true;
});
auto scrollDateOpacity = _scrollDateOpacity.current(ms, _scrollDateShown ? 1. : 0.);
enumerateDates([&p, &r, scrollDateOpacity](HistoryItem *item, int itemtop, int dateTop) {
int dateHeight = st::msgServicePadding.bottom() + st::msgServiceFont->height + st::msgServicePadding.top();
int dateHeight = st::msgServicePadding.bottom() + st::msgServiceFont->height + st::msgServicePadding.top();
//QDate lastDate;
//if (!_history->isEmpty()) {
// lastDate = _history->blocks.back()->items.back()->date.date();
//}
//// if item top is before this value always show date as a floating date
//int showFloatingBefore = height() - 2 * (_visibleAreaBottom - _visibleAreaTop) - dateHeight;
auto scrollDateOpacity = _scrollDateOpacity.current(ms, _scrollDateShown ? 1. : 0.);
enumerateDates([&p, &r, scrollDateOpacity, dateHeight/*, lastDate, showFloatingBefore*/](HistoryItem *item, int itemtop, int dateTop) {
// stop the enumeration if the date is above the painted rect
if (dateTop + dateHeight <= r.top()) {
return false;
}
bool dateInPlace = item->displayDate();
bool displayDate = item->displayDate();
bool dateInPlace = displayDate;
if (dateInPlace) {
int correctDateTop = itemtop + st::msgServiceMargin.top();
dateInPlace = (dateTop < correctDateTop + dateHeight);
}
//bool noFloatingDate = (item->date.date() == lastDate && displayDate);
//if (noFloatingDate) {
// if (itemtop < showFloatingBefore) {
// noFloatingDate = false;
// }
//}
// paint the date if it intersects the painted rect
if (dateTop < r.top() + r.height()) {
auto opacity = dateInPlace ? 1. : scrollDateOpacity;
auto opacity = (dateInPlace/* || noFloatingDate*/) ? 1. : scrollDateOpacity;
if (opacity > 0.) {
p.setOpacity(opacity);
int dateY = dateTop - st::msgServiceMargin.top(), width = item->history()->width;
int dateY = /*noFloatingDate ? itemtop :*/ (dateTop - st::msgServiceMargin.top());
int width = item->history()->width;
if (auto date = item->Get<HistoryMessageDate>()) {
date->paint(p, dateY, width);
} else {
@ -1034,6 +1044,12 @@ void HistoryInner::dragActionFinish(const QPoint &screenPos, Qt::MouseButton but
_dragSelType = TextSelectType::Letters;
_widget->noSelectingScroll();
_widget->updateTopBarSelection();
#if defined Q_OS_LINUX32 || defined Q_OS_LINUX64
if (!_selected.isEmpty() && _selected.cbegin().value() != FullSelection) {
setToClipboard(_selected.cbegin().key()->selectedText(_selected.cbegin().value()), QClipboard::Selection);
}
#endif // Q_OS_LINUX32 || Q_OS_LINUX64
}
void HistoryInner::mouseReleaseEvent(QMouseEvent *e) {
@ -1293,7 +1309,7 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
void HistoryInner::onMenuDestroy(QObject *obj) {
if (_menu == obj) {
_menu = 0;
_menu = nullptr;
}
}
@ -1391,9 +1407,9 @@ void HistoryInner::copyContextText() {
setToClipboard(item->selectedText(FullSelection));
}
void HistoryInner::setToClipboard(const TextWithEntities &forClipboard) {
void HistoryInner::setToClipboard(const TextWithEntities &forClipboard, QClipboard::Mode mode) {
if (auto data = mimeDataFromTextWithEntities(forClipboard)) {
QApplication::clipboard()->setMimeData(data);
QApplication::clipboard()->setMimeData(data, mode);
}
}
@ -1615,10 +1631,20 @@ void HistoryInner::visibleAreaUpdated(int top, int bottom) {
_scrollDateCheck.call();
}
bool HistoryInner::displayScrollDate() const{
return (_visibleAreaTop <= height() - 2 * (_visibleAreaBottom - _visibleAreaTop));
}
void HistoryInner::onScrollDateCheck() {
if (!_history) return;
auto newScrollDateItem = _history->scrollTopItem ? _history->scrollTopItem : (_migrated ? _migrated->scrollTopItem : nullptr);
auto newScrollDateItemTop = _history->scrollTopItem ? _history->scrollTopOffset : (_migrated ? _migrated->scrollTopOffset : 0);
//if (newScrollDateItem && !displayScrollDate()) {
// if (!_history->isEmpty() && newScrollDateItem->date.date() == _history->blocks.back()->items.back()->date.date()) {
// newScrollDateItem = nullptr;
// }
//}
if (!newScrollDateItem) {
_scrollDateLastItem = nullptr;
_scrollDateLastItemTop = 0;
@ -3460,7 +3486,7 @@ void HistoryWidget::onRecordDone(QByteArray result, VoiceWaveform waveform, qint
App::wnd()->activateWindow();
int32 duration = samples / AudioVoiceMsgFrequency;
_fileLoader.addTask(new FileLoadTask(result, duration, waveform, FileLoadTo(_peer->id, _silent.checked(), replyToId())));
cancelReply(lastForceReplyReplied());
cancelReplyAfterMediaSend(lastForceReplyReplied());
}
void HistoryWidget::onRecordUpdate(quint16 level, qint32 samples) {
@ -3940,6 +3966,8 @@ void HistoryWidget::showHistory(const PeerId &peerId, MsgId showAtMsgId, bool re
updateBotKeyboard();
}
App::clearMousedItems();
_addToScroll = 0;
_saveEditMsgRequestId = 0;
_replyEditMsg = nullptr;
@ -5144,7 +5172,7 @@ void HistoryWidget::shareContact(const PeerId &peer, const QString &phone, const
App::historyRegRandom(randomId, newId);
App::main()->finishForwarding(history, _silent.checked());
cancelReply(lastKeyboardUsed);
cancelReplyAfterMediaSend(lastKeyboardUsed);
}
void HistoryWidget::onSendPaths(const PeerId &peer) {
@ -5500,6 +5528,7 @@ void HistoryWidget::sendBotCommand(PeerData *peer, UserData *bot, const QString
if (replyTo) {
if (_replyToId == replyTo) {
cancelReply();
onCloudDraftSave();
}
if (_keyboard.singleUse() && _keyboard.hasMarkup() && lastKeyboardUsed) {
if (_kbShown) onKbToggle(false);
@ -6251,7 +6280,7 @@ void HistoryWidget::uploadFiles(const QStringList &files, PrepareMediaType type)
}
_fileLoader.addTasks(tasks);
cancelReply(lastForceReplyReplied());
cancelReplyAfterMediaSend(lastForceReplyReplied());
}
void HistoryWidget::uploadFileContent(const QByteArray &fileContent, PrepareMediaType type) {
@ -6259,7 +6288,7 @@ void HistoryWidget::uploadFileContent(const QByteArray &fileContent, PrepareMedi
App::wnd()->activateWindow();
_fileLoader.addTask(new FileLoadTask(fileContent, type, FileLoadTo(_peer->id, _silent.checked(), replyToId())));
cancelReply(lastForceReplyReplied());
cancelReplyAfterMediaSend(lastForceReplyReplied());
}
void HistoryWidget::shareContactWithConfirm(const QString &phone, const QString &fname, const QString &lname, MsgId replyTo, bool withText) {
@ -6271,6 +6300,7 @@ void HistoryWidget::shareContactWithConfirm(const QString &phone, const QString
}
void HistoryWidget::confirmSendFile(const FileLoadResultPtr &file, bool ctrlShiftEnter) {
bool lastKeyboardUsed = lastForceReplyReplied(FullMsgId(peerToChannel(file->to.peer), file->to.replyTo));
if (_confirmWithTextId && _confirmWithTextId == file->id) {
onSend(ctrlShiftEnter, file->to.replyTo);
_confirmWithTextId = 0;
@ -6323,6 +6353,8 @@ void HistoryWidget::confirmSendFile(const FileLoadResultPtr &file, bool ctrlShif
}
App::main()->dialogsToUp();
peerMessagesUpdated(file->to.peer);
cancelReplyAfterMediaSend(lastKeyboardUsed);
}
void HistoryWidget::cancelSendFile(const FileLoadResultPtr &file) {
@ -7132,7 +7164,7 @@ void HistoryWidget::onInlineResultSend(InlineBots::Result *result, UserData *bot
bool out = !_peer->isSelf(), unread = !_peer->isSelf();
MTPDmessage::Flags flags = newMessageFlags(_peer) | MTPDmessage::Flag::f_media; // unread, out
MTPmessages_SendInlineBotResult::Flags sendFlags = 0;
MTPmessages_SendInlineBotResult::Flags sendFlags = MTPmessages_SendInlineBotResult::Flag::f_clear_draft;
if (replyToId()) {
flags |= MTPDmessage::Flag::f_reply_to_msg_id;
sendFlags |= MTPmessages_SendInlineBotResult::Flag::f_reply_to_msg_id;
@ -7168,10 +7200,9 @@ void HistoryWidget::onInlineResultSend(InlineBots::Result *result, UserData *bot
App::historyRegRandom(randomId, newId);
clearFieldText();
//_saveDraftText = true;
//_saveDraftStart = getms();
//onDraftSave();
onCloudDraftSave(); // won't be needed if SendInlineBotResult will clear the cloud draft
_saveDraftText = true;
_saveDraftStart = getms();
onDraftSave();
RecentInlineBots &bots(cRefRecentInlineBots());
int32 index = bots.indexOf(bot);
@ -7334,7 +7365,7 @@ void HistoryWidget::sendExistingDocument(DocumentData *doc, const QString &capti
_history->sendRequestId = MTP::send(MTPmessages_SendMedia(MTP_flags(sendFlags), _peer->input, MTP_int(replyToId()), MTP_inputMediaDocument(mtpInput, MTP_string(caption)), MTP_long(randomId), MTPnullMarkup), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcFail(&MainWidget::sendMessageFail), 0, 0, _history->sendRequestId);
App::main()->finishForwarding(_history, _silent.checked());
cancelReply(lastKeyboardUsed);
cancelReplyAfterMediaSend(lastKeyboardUsed);
if (doc->sticker()) App::main()->incrementSticker(doc);
@ -7390,7 +7421,7 @@ void HistoryWidget::sendExistingPhoto(PhotoData *photo, const QString &caption)
_history->sendRequestId = MTP::send(MTPmessages_SendMedia(MTP_flags(sendFlags), _peer->input, MTP_int(replyToId()), MTP_inputMediaPhoto(MTP_inputPhoto(MTP_long(photo->id), MTP_long(photo->access)), MTP_string(caption)), MTP_long(randomId), MTPnullMarkup), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcFail(&MainWidget::sendMessageFail), 0, 0, _history->sendRequestId);
App::main()->finishForwarding(_history, _silent.checked());
cancelReply(lastKeyboardUsed);
cancelReplyAfterMediaSend(lastKeyboardUsed);
App::historyRegRandom(randomId, newId);
@ -7590,7 +7621,7 @@ bool HistoryWidget::lastForceReplyReplied(const FullMsgId &replyTo) const {
return _keyboard.forceReply() && _keyboard.forMsgId() == FullMsgId(_channel, _history->lastKeyboardId) && _keyboard.forMsgId().msg == (replyTo.msg < 0 ? replyToId() : replyTo.msg);
}
void HistoryWidget::cancelReply(bool lastKeyboardUsed) {
bool HistoryWidget::cancelReply(bool lastKeyboardUsed) {
bool wasReply = false;
if (_replyToId) {
wasReply = true;
@ -7626,6 +7657,13 @@ void HistoryWidget::cancelReply(bool lastKeyboardUsed) {
onKbToggle(false);
}
}
return wasReply;
}
void HistoryWidget::cancelReplyAfterMediaSend(bool lastKeyboardUsed) {
if (cancelReply(lastKeyboardUsed)) {
onCloudDraftSave();
}
}
void HistoryWidget::cancelEdit() {

View File

@ -155,10 +155,11 @@ private:
HistoryItem *nextItem(HistoryItem *item);
void updateDragSelection(HistoryItem *dragSelFrom, HistoryItem *dragSelTo, bool dragSelecting, bool force = false);
void setToClipboard(const TextWithEntities &forClipboard);
void setToClipboard(const TextWithEntities &forClipboard, QClipboard::Mode mode = QClipboard::Clipboard);
void toggleScrollDateShown();
void repaintScrollDateCallback();
bool displayScrollDate() const;
PeerData *_peer = nullptr;
History *_migrated = nullptr;
@ -272,11 +273,10 @@ private:
template <typename Method>
void enumerateItemsInHistory(History *history, int historytop, Method method);
template <typename Method, typename SwitchToMigratedCallback>
void enumerateItems(Method method, SwitchToMigratedCallback switchToMigrated) {
template <typename Method>
void enumerateItems(Method method) {
enumerateItemsInHistory(_history, historyTop(), method);
if (_migrated) {
switchToMigrated();
enumerateItemsInHistory(_migrated, migratedTop(), method);
}
}
@ -637,7 +637,7 @@ public:
MsgId replyToId() const;
void messageDataReceived(ChannelData *channel, MsgId msgId);
bool lastForceReplyReplied(const FullMsgId &replyTo = FullMsgId(NoChannel, -1)) const;
void cancelReply(bool lastKeyboardUsed = false);
bool cancelReply(bool lastKeyboardUsed = false);
void cancelEdit();
void updateForwarding(bool force = false);
void cancelForwarding(); // called by MainWidget
@ -869,6 +869,8 @@ private:
// Request to show results in the emoji panel.
void applyInlineBotQuery(UserData *bot, const QString &query);
void cancelReplyAfterMediaSend(bool lastKeyboardUsed);
MsgId _replyToId = 0;
Text _replyToName;
int _replyToNameVersion = 0;

View File

@ -630,6 +630,36 @@ void MainWidget::deleteLayer(int32 selectedCount) {
Ui::showLayer(box);
}
void MainWidget::deletePhotoLayer(PhotoData *photo) {
_deletingPhoto = photo;
onDeletePhotoSure(); // langs are not ready yet
//auto box = new ConfirmBox(lang(lng_delete_photo_sure), lang(lng_box_delete));
//connect(box, SIGNAL(confirmed()), this, SLOT(onDeletePhotoSure()));
//Ui::showLayer(box);
}
void MainWidget::onDeletePhotoSure() {
Ui::hideLayer();
auto me = App::self();
auto photo = _deletingPhoto;
if (!photo || !me) return;
if (me->photoId == photo->id) {
App::app()->peerClearPhoto(me->id);
} else if (photo->peer && !photo->peer->isUser() && photo->peer->photoId == photo->id) {
App::app()->peerClearPhoto(photo->peer->id);
} else {
for (int i = 0, l = me->photos.size(); i != l; ++i) {
if (me->photos.at(i) == photo) {
me->photos.removeAt(i);
MTP::send(MTPphotos_DeletePhotos(MTP_vector<MTPInputPhoto>(1, MTP_inputPhoto(MTP_long(photo->id), MTP_long(photo->access)))));
break;
}
}
}
}
void MainWidget::shareContactLayer(UserData *contact) {
hiderLayer(new HistoryHider(this, contact));
}
@ -1680,9 +1710,7 @@ void MainWidget::updateOnlineDisplay() {
}
void MainWidget::onSendFileConfirm(const FileLoadResultPtr &file, bool ctrlShiftEnter) {
bool lastKeyboardUsed = _history->lastForceReplyReplied(FullMsgId(peerToChannel(file->to.peer), file->to.replyTo));
_history->confirmSendFile(file, ctrlShiftEnter);
_history->cancelReply(lastKeyboardUsed);
}
void MainWidget::onSendFileCancel(const FileLoadResultPtr &file) {

View File

@ -263,6 +263,8 @@ public:
void offerPeer(PeerId peer);
void dialogsActivate();
void deletePhotoLayer(PhotoData *photo);
DragState getDragState(const QMimeData *mime);
bool leaveChatFailed(PeerData *peer, const RPCError &e);
@ -490,6 +492,10 @@ public slots:
void ui_showPeerHistoryAsync(quint64 peerId, qint32 showAtMsgId);
void ui_autoplayMediaInlineAsync(qint32 channelId, qint32 msgId);
private slots:
void onDeletePhotoSure();
private:
void sendReadRequest(PeerData *peer, MsgId upTo);
void channelReadDone(PeerData *peer, const MTPBool &result);
@ -657,6 +663,8 @@ private:
typedef QMap<ChannelData*, bool> UpdatedChannels;
UpdatedChannels _updatedChannels;
PhotoData *_deletingPhoto = nullptr;
typedef QMap<MsgId, bool> ViewsIncrementMap;
typedef QMap<PeerData*, ViewsIncrementMap> ViewsIncrement;
ViewsIncrement _viewsIncremented, _viewsToIncrement;

View File

@ -690,32 +690,10 @@ void MediaView::onForward() {
void MediaView::onDelete() {
close();
if (!_msgid) {
if (App::self() && _photo && App::self()->photoId == _photo->id) {
App::app()->peerClearPhoto(App::self()->id);
} else if (_user && _user == App::self()) {
for (int32 i = 0, l = _user->photos.size(); i != l; ++i) {
if (_user->photos.at(i) == _photo) {
_user->photos.removeAt(i);
MTP::send(MTPphotos_DeletePhotos(MTP_vector<MTPInputPhoto>(1, MTP_inputPhoto(MTP_long(_photo->id), MTP_long(_photo->access)))), rpcDone(&MediaView::deletePhotosDone), rpcFail(&MediaView::deletePhotosFail));
if (_user->photos.isEmpty()) {
hide();
} else if (i + 1 < l) {
showPhoto(_user->photos.at(i), _user);
} else {
showPhoto(_user->photos.at(i - 1), _user);
}
break;
}
}
} else if (_photo->peer && _photo->peer->photoId == _photo->id) {
App::app()->peerClearPhoto(_photo->peer->id);
}
} else {
HistoryItem *item = App::histItemById(_msgmigrated ? 0 : _channel, _msgid);
if (item) {
App::contextItem(item);
App::main()->deleteLayer();
}
App::main()->deletePhotoLayer(_photo);
} else if (auto item = App::histItemById(_msgmigrated ? 0 : _channel, _msgid)) {
App::contextItem(item);
App::main()->deleteLayer();
}
}
@ -2186,15 +2164,6 @@ void MediaView::userPhotosLoaded(UserData *u, const MTPphotos_Photos &photos, mt
if (App::wnd()) App::wnd()->mediaOverviewUpdated(u, OverviewCount);
}
void MediaView::deletePhotosDone(const MTPVector<MTPlong> &result) {
}
bool MediaView::deletePhotosFail(const RPCError &error) {
if (MTP::isDefaultHandledError(error)) return false;
return true;
}
void MediaView::updateHeader() {
int32 index = _index, count = 0, addcount = (_migrated && _overview != OverviewCount) ? _migrated->overviewCount(_overview) : 0;
if (_history) {

View File

@ -236,7 +236,7 @@ with open('scheme.tl') as f:
maxbit = max(maxbit, int(conditions[paramName]));
if (maxbit > 0):
funcsText += '\n';
funcsText += '\n\t\tMAX_FIELD = (1 << ' + str(maxbit) + '),\n';
funcsText += '\t\tMAX_FIELD = (1 << ' + str(maxbit) + '),\n';
funcsText += '\t};\n';
funcsText += '\tQ_DECLARE_FLAGS(Flags, Flag);\n';
funcsText += '\tfriend inline Flags operator~(Flag v) { return QFlag(~static_cast<int32>(v)); }\n';

View File

@ -774,7 +774,7 @@ messages.deleteMessages#a5f18925 id:Vector<int> = messages.AffectedMessages;
messages.receivedMessages#5a954c0 max_id:int = Vector<ReceivedNotifyMessage>;
messages.setTyping#a3825e50 peer:InputPeer action:SendMessageAction = Bool;
messages.sendMessage#fa88427a flags:# no_webpage:flags.1?true silent:flags.5?true background:flags.6?true clear_draft:flags.7?true peer:InputPeer reply_to_msg_id:flags.0?int message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> = Updates;
messages.sendMedia#c8f16791 flags:# silent:flags.5?true background:flags.6?true peer:InputPeer reply_to_msg_id:flags.0?int media:InputMedia random_id:long reply_markup:flags.2?ReplyMarkup = Updates;
messages.sendMedia#c8f16791 flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true peer:InputPeer reply_to_msg_id:flags.0?int media:InputMedia random_id:long reply_markup:flags.2?ReplyMarkup = Updates;
messages.forwardMessages#708e0195 flags:# silent:flags.5?true background:flags.6?true from_peer:InputPeer id:Vector<int> random_id:Vector<long> to_peer:InputPeer = Updates;
messages.reportSpam#cf1592db peer:InputPeer = Bool;
messages.hideReportSpam#a8f1709b peer:InputPeer = Bool;
@ -821,7 +821,7 @@ messages.getSavedGifs#83bf3d52 hash:int = messages.SavedGifs;
messages.saveGif#327a30cb id:InputDocument unsave:Bool = Bool;
messages.getInlineBotResults#514e999d flags:# bot:InputUser peer:InputPeer geo_point:flags.0?InputGeoPoint query:string offset:string = messages.BotResults;
messages.setInlineBotResults#eb5ea206 flags:# gallery:flags.0?true private:flags.1?true query_id:long results:Vector<InputBotInlineResult> cache_time:int next_offset:flags.2?string switch_pm:flags.3?InlineBotSwitchPM = Bool;
messages.sendInlineBotResult#b16e06fe flags:# silent:flags.5?true background:flags.6?true peer:InputPeer reply_to_msg_id:flags.0?int random_id:long query_id:long id:string = Updates;
messages.sendInlineBotResult#b16e06fe flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true peer:InputPeer reply_to_msg_id:flags.0?int random_id:long query_id:long id:string = Updates;
messages.getMessageEditData#fda68d36 peer:InputPeer id:int = messages.MessageEditData;
messages.editMessage#ce91e4ca flags:# no_webpage:flags.1?true peer:InputPeer id:int message:flags.11?string reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> = Updates;
messages.editInlineBotMessage#130c2c85 flags:# no_webpage:flags.1?true id:InputBotInlineMessageID message:flags.11?string reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> = Bool;

View File

@ -7237,11 +7237,12 @@ void _serialize_messages_sendMedia(MTPStringLogger &to, int32 stage, int32 lev,
case 0: to.add(" flags: "); ++stages.back(); if (start >= end) throw Exception("start >= end in flags"); else flags.back() = *start; types.push_back(mtpc_flags); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
case 1: to.add(" silent: "); ++stages.back(); if (flag & MTPmessages_sendMedia::Flag::f_silent) { to.add("YES [ BY BIT 5 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 5 IN FIELD flags ]"); } break;
case 2: to.add(" background: "); ++stages.back(); if (flag & MTPmessages_sendMedia::Flag::f_background) { to.add("YES [ BY BIT 6 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 6 IN FIELD flags ]"); } break;
case 3: to.add(" peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
case 4: to.add(" reply_to_msg_id: "); ++stages.back(); if (flag & MTPmessages_sendMedia::Flag::f_reply_to_msg_id) { types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break;
case 5: to.add(" media: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
case 6: to.add(" random_id: "); ++stages.back(); types.push_back(mtpc_long+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
case 7: to.add(" reply_markup: "); ++stages.back(); if (flag & MTPmessages_sendMedia::Flag::f_reply_markup) { types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 2 IN FIELD flags ]"); } break;
case 3: to.add(" clear_draft: "); ++stages.back(); if (flag & MTPmessages_sendMedia::Flag::f_clear_draft) { to.add("YES [ BY BIT 7 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 7 IN FIELD flags ]"); } break;
case 4: to.add(" peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
case 5: to.add(" reply_to_msg_id: "); ++stages.back(); if (flag & MTPmessages_sendMedia::Flag::f_reply_to_msg_id) { types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break;
case 6: to.add(" media: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
case 7: to.add(" random_id: "); ++stages.back(); types.push_back(mtpc_long+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
case 8: to.add(" reply_markup: "); ++stages.back(); if (flag & MTPmessages_sendMedia::Flag::f_reply_markup) { types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 2 IN FIELD flags ]"); } break;
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
}
}
@ -7438,11 +7439,12 @@ void _serialize_messages_sendInlineBotResult(MTPStringLogger &to, int32 stage, i
case 0: to.add(" flags: "); ++stages.back(); if (start >= end) throw Exception("start >= end in flags"); else flags.back() = *start; types.push_back(mtpc_flags); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
case 1: to.add(" silent: "); ++stages.back(); if (flag & MTPmessages_sendInlineBotResult::Flag::f_silent) { to.add("YES [ BY BIT 5 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 5 IN FIELD flags ]"); } break;
case 2: to.add(" background: "); ++stages.back(); if (flag & MTPmessages_sendInlineBotResult::Flag::f_background) { to.add("YES [ BY BIT 6 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 6 IN FIELD flags ]"); } break;
case 3: to.add(" peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
case 4: to.add(" reply_to_msg_id: "); ++stages.back(); if (flag & MTPmessages_sendInlineBotResult::Flag::f_reply_to_msg_id) { types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break;
case 5: to.add(" random_id: "); ++stages.back(); types.push_back(mtpc_long+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
case 6: to.add(" query_id: "); ++stages.back(); types.push_back(mtpc_long+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
case 7: to.add(" id: "); ++stages.back(); types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
case 3: to.add(" clear_draft: "); ++stages.back(); if (flag & MTPmessages_sendInlineBotResult::Flag::f_clear_draft) { to.add("YES [ BY BIT 7 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 7 IN FIELD flags ]"); } break;
case 4: to.add(" peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
case 5: to.add(" reply_to_msg_id: "); ++stages.back(); if (flag & MTPmessages_sendInlineBotResult::Flag::f_reply_to_msg_id) { types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break;
case 6: to.add(" random_id: "); ++stages.back(); types.push_back(mtpc_long+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
case 7: to.add(" query_id: "); ++stages.back(); types.push_back(mtpc_long+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
case 8: to.add(" id: "); ++stages.back(); types.push_back(mtpc_string+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
}
}

View File

@ -15064,7 +15064,6 @@ public:
enum class Flag : int32 {
f_allow_flashcall = (1 << 0),
f_current_number = (1 << 0),
MAX_FIELD = (1 << 0),
};
Q_DECLARE_FLAGS(Flags, Flag);
@ -15897,7 +15896,6 @@ public:
f_last_name = (1 << 1),
f_about = (1 << 2),
MAX_FIELD = (1 << 2),
};
Q_DECLARE_FLAGS(Flags, Flag);
@ -16340,7 +16338,6 @@ public:
enum class Flag : int32 {
f_allow_flashcall = (1 << 0),
f_current_number = (1 << 0),
MAX_FIELD = (1 << 0),
};
Q_DECLARE_FLAGS(Flags, Flag);
@ -17208,7 +17205,6 @@ public:
f_groups = (1 << 10),
f_channels = (1 << 15),
MAX_FIELD = (1 << 15),
};
Q_DECLARE_FLAGS(Flags, Flag);
@ -17457,7 +17453,6 @@ public:
class MTPmessages_search { // RPC method 'messages.search'
public:
enum class Flag : int32 {
MAX_FIELD = (1 << 0),
};
Q_DECLARE_FLAGS(Flags, Flag);
@ -17570,7 +17565,6 @@ class MTPmessages_deleteHistory { // RPC method 'messages.deleteHistory'
public:
enum class Flag : int32 {
f_just_clear = (1 << 0),
MAX_FIELD = (1 << 0),
};
Q_DECLARE_FLAGS(Flags, Flag);
@ -17754,7 +17748,6 @@ public:
f_reply_markup = (1 << 2),
f_entities = (1 << 3),
MAX_FIELD = (1 << 7),
};
Q_DECLARE_FLAGS(Flags, Flag);
@ -17830,17 +17823,18 @@ public:
enum class Flag : int32 {
f_silent = (1 << 5),
f_background = (1 << 6),
f_clear_draft = (1 << 7),
f_reply_to_msg_id = (1 << 0),
f_reply_markup = (1 << 2),
MAX_FIELD = (1 << 6),
MAX_FIELD = (1 << 7),
};
Q_DECLARE_FLAGS(Flags, Flag);
friend inline Flags operator~(Flag v) { return QFlag(~static_cast<int32>(v)); }
bool is_silent() const { return vflags.v & Flag::f_silent; }
bool is_background() const { return vflags.v & Flag::f_background; }
bool is_clear_draft() const { return vflags.v & Flag::f_clear_draft; }
bool has_reply_to_msg_id() const { return vflags.v & Flag::f_reply_to_msg_id; }
bool has_reply_markup() const { return vflags.v & Flag::f_reply_markup; }
@ -17904,7 +17898,6 @@ public:
f_silent = (1 << 5),
f_background = (1 << 6),
MAX_FIELD = (1 << 6),
};
Q_DECLARE_FLAGS(Flags, Flag);
@ -19774,7 +19767,6 @@ class MTPmessages_getInlineBotResults { // RPC method 'messages.getInlineBotResu
public:
enum class Flag : int32 {
f_geo_point = (1 << 0),
MAX_FIELD = (1 << 0),
};
Q_DECLARE_FLAGS(Flags, Flag);
@ -19844,7 +19836,6 @@ public:
f_next_offset = (1 << 2),
f_switch_pm = (1 << 3),
MAX_FIELD = (1 << 3),
};
Q_DECLARE_FLAGS(Flags, Flag);
@ -19914,16 +19905,17 @@ public:
enum class Flag : int32 {
f_silent = (1 << 5),
f_background = (1 << 6),
f_clear_draft = (1 << 7),
f_reply_to_msg_id = (1 << 0),
MAX_FIELD = (1 << 6),
MAX_FIELD = (1 << 7),
};
Q_DECLARE_FLAGS(Flags, Flag);
friend inline Flags operator~(Flag v) { return QFlag(~static_cast<int32>(v)); }
bool is_silent() const { return vflags.v & Flag::f_silent; }
bool is_background() const { return vflags.v & Flag::f_background; }
bool is_clear_draft() const { return vflags.v & Flag::f_clear_draft; }
bool has_reply_to_msg_id() const { return vflags.v & Flag::f_reply_to_msg_id; }
MTPflags<MTPmessages_sendInlineBotResult::Flags> vflags;
@ -20030,7 +20022,6 @@ public:
f_reply_markup = (1 << 2),
f_entities = (1 << 3),
MAX_FIELD = (1 << 11),
};
Q_DECLARE_FLAGS(Flags, Flag);
@ -20103,7 +20094,6 @@ public:
f_reply_markup = (1 << 2),
f_entities = (1 << 3),
MAX_FIELD = (1 << 11),
};
Q_DECLARE_FLAGS(Flags, Flag);
@ -20216,7 +20206,6 @@ public:
f_alert = (1 << 1),
f_message = (1 << 0),
MAX_FIELD = (1 << 1),
};
Q_DECLARE_FLAGS(Flags, Flag);
@ -20316,7 +20305,6 @@ public:
f_reply_to_msg_id = (1 << 0),
f_entities = (1 << 3),
MAX_FIELD = (1 << 3),
};
Q_DECLARE_FLAGS(Flags, Flag);
@ -21490,7 +21478,6 @@ public:
f_broadcast = (1 << 0),
f_megagroup = (1 << 1),
MAX_FIELD = (1 << 1),
};
Q_DECLARE_FLAGS(Flags, Flag);
@ -22172,7 +22159,6 @@ class MTPchannels_updatePinnedMessage { // RPC method 'channels.updatePinnedMess
public:
enum class Flag : int32 {
f_silent = (1 << 0),
MAX_FIELD = (1 << 0),
};
Q_DECLARE_FLAGS(Flags, Flag);

View File

@ -730,6 +730,8 @@ void OverviewInner::clear() {
}
_layoutDates.clear();
_items.clear();
App::clearMousedItems();
}
int32 OverviewInner::itemTop(const FullMsgId &msgId) const {

View File

@ -29,8 +29,10 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
namespace Profile {
using UpdateFlag = Notify::PeerUpdate::Flag;
InviteLinkWidget::InviteLinkWidget(QWidget *parent, PeerData *peer) : BlockWidget(parent, peer, lang(lng_profile_invite_link_section)) {
auto observeEvents = Notify::PeerUpdate::Flag::InviteLinkChanged;
auto observeEvents = UpdateFlag::InviteLinkChanged | UpdateFlag::UsernameChanged;
Notify::registerPeerObserver(observeEvents, this, &InviteLinkWidget::notifyPeerUpdated);
refreshLink();
@ -42,7 +44,7 @@ void InviteLinkWidget::notifyPeerUpdated(const Notify::PeerUpdate &update) {
return;
}
if (update.flags & Notify::PeerUpdate::Flag::InviteLinkChanged) {
if (update.flags & (UpdateFlag::InviteLinkChanged | UpdateFlag::UsernameChanged)) {
refreshLink();
refreshVisibility();
@ -79,7 +81,7 @@ QString InviteLinkWidget::getInviteLink() const {
if (auto chat = peer()->asChat()) {
return chat->inviteLink();
} else if (auto channel = peer()->asChannel()) {
return channel->inviteLink();
return channel->isPublic() ? QString() : channel->inviteLink();
}
return QString();
};
@ -87,7 +89,9 @@ QString InviteLinkWidget::getInviteLink() const {
void InviteLinkWidget::refreshLink() {
_link.destroy();
TextWithEntities linkData = { getInviteLink(), EntitiesInText() };
if (!linkData.text.isEmpty()) {
if (linkData.text.isEmpty()) {
_link.destroy();
} else {
_link = new FlatLabel(this, QString(), FlatLabel::InitType::Simple, st::profileInviteLinkText);
_link->show();

View File

@ -147,7 +147,9 @@ void SettingsWidget::refreshInviteLinkButton() {
return QString();
};
auto inviteLinkText = getInviteLinkText();
if (!inviteLinkText.isEmpty()) {
if (inviteLinkText.isEmpty()) {
_inviteLink.destroy();
} else {
_inviteLink = new Ui::LeftOutlineButton(this, inviteLinkText, st::defaultLeftOutlineButton);
_inviteLink->show();
connect(_inviteLink, SIGNAL(clicked()), this, SLOT(onInviteLink()));

View File

@ -69,10 +69,8 @@ void UserpicButton::notifyPeerUpdated(const Notify::PeerUpdate &update) {
}
void UserpicButton::notifyImageLoaded() {
LOG(("IMAGE LOADED!"));
if (_waiting && _peer->userpicLoaded()) {
_waiting = false;
LOG(("STARTED SHOWING"));
startNewPhotoShowing();
}
}
@ -97,14 +95,12 @@ void UserpicButton::startNewPhotoShowing() {
_oldUserpic = myGrab(this);
_userpic = prepareUserpicPixmap();
LOG(("FROM STARTED SHOWING: %1").arg(Logs::b(_notShownYet)));
if (_notShownYet) {
return;
}
_a_appearance.finish();
START_ANIMATION(_a_appearance, func(this, &UserpicButton::refreshCallback), 0, 1, st::profilePhotoDuration, anim::linear);
LOG(("UPDATE FROM STARTED SHOWING"));
update();
}

View File

@ -208,6 +208,8 @@ SettingsInner::SettingsInner(SettingsWidget *parent) : TWidget(parent)
, _supportGetRequest(0) {
Notify::registerPeerObserver(Notify::PeerUpdate::Flag::UsernameChanged, this, &SettingsInner::notifyPeerUpdated);
App::clearMousedItems();
if (self()) {
self()->loadUserpic();

View File

@ -234,6 +234,13 @@ Text::StateResult FlatLabel::dragActionFinish(const QPoint &p, Qt::MouseButton b
App::activateClickHandler(activated, button);
}
}
#if defined Q_OS_LINUX32 || defined Q_OS_LINUX64
if (!_selection.empty()) {
QApplication::clipboard()->setText(_text.originalText(_selection, _contextExpandLinksMode), QClipboard::Selection);
}
#endif // Q_OS_LINUX32 || Q_OS_LINUX64
return state;
}