2014-11-05 20:43:32 +03:00
/*
2014-05-30 12:53:19 +04:00
This file is part of Telegram Desktop ,
2014-12-01 13:47:38 +03:00
the official desktop version of Telegram messaging app , see https : //telegram.org
2014-05-30 12:53:19 +04:00
Telegram Desktop is free software : you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation , either version 3 of the License , or
( at your option ) any later version .
It is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
2015-10-03 16:16:42 +03:00
In addition , as a special exception , the copyright holders give permission
to link the code of portions of this program with the OpenSSL library .
2014-05-30 12:53:19 +04:00
Full license : https : //github.com/telegramdesktop/tdesktop/blob/master/LICENSE
2016-02-08 13:56:18 +03:00
Copyright ( c ) 2014 - 2016 John Preston , https : //desktop.telegram.org
2014-05-30 12:53:19 +04:00
*/
# include "stdafx.h"
2016-04-10 22:18:26 +04:00
# include "mainwidget.h"
2016-04-13 00:31:28 +03:00
# include "ui/buttons/peer_avatar_button.h"
2016-05-19 15:03:51 +03:00
# include "window/section_memento.h"
# include "window/section_widget.h"
2016-04-13 00:31:28 +03:00
# include "window/top_bar_widget.h"
2016-05-25 15:09:05 +03:00
# include "observer_peer.h"
2016-04-13 00:31:28 +03:00
# include "apiwrap.h"
# include "dialogswidget.h"
# include "historywidget.h"
# include "profilewidget.h"
# include "overviewwidget.h"
# include "playerwidget.h"
2014-05-30 12:53:19 +04:00
# include "lang.h"
# include "boxes/addcontactbox.h"
2015-12-24 22:26:28 +03:00
# include "fileuploader.h"
2014-05-30 12:53:19 +04:00
# include "application.h"
2016-04-13 00:31:28 +03:00
# include "mainwindow.h"
2014-05-30 12:53:19 +04:00
# include "settingswidget.h"
2016-04-10 22:18:26 +04:00
# include "inline_bots/inline_bot_layout_item.h"
2014-05-30 12:53:19 +04:00
# include "boxes/confirmbox.h"
2015-05-19 18:46:45 +03:00
# include "boxes/stickersetbox.h"
2015-06-17 22:43:03 +03:00
# include "boxes/contactsbox.h"
2015-11-26 20:34:52 +03:00
# include "boxes/downloadpathbox.h"
2015-01-02 17:55:24 +03:00
# include "localstorage.h"
2016-03-17 12:23:38 +03:00
# include "shortcuts.h"
2014-09-04 11:33:44 +04:00
# include "audio.h"
2016-04-05 11:45:53 +04:00
2016-05-19 15:03:51 +03:00
StackItemSection : : StackItemSection ( std_ : : unique_ptr < Window : : SectionMemento > & & memento ) : StackItem ( nullptr )
, _memento ( std_ : : move ( memento ) ) {
}
StackItemSection : : ~ StackItemSection ( ) {
}
2016-04-13 00:31:28 +03:00
MainWidget : : MainWidget ( MainWindow * window ) : TWidget ( window )
2015-12-08 15:33:37 +03:00
, _a_show ( animation ( this , & MainWidget : : step_show ) )
2016-05-14 19:57:06 +03:00
, _sideShadow ( this , st : : shadowColor )
2016-04-13 00:31:28 +03:00
, _dialogs ( this )
, _history ( this )
2015-10-17 16:52:26 +02:00
, _player ( this )
, _topBar ( this )
, _mediaType ( this )
, _api ( new ApiWrap ( this ) ) {
2014-05-30 12:53:19 +04:00
setGeometry ( QRect ( 0 , st : : titleHeight , App : : wnd ( ) - > width ( ) , App : : wnd ( ) - > height ( ) - st : : titleHeight ) ) ;
2015-09-21 23:57:42 +03:00
MTP : : setGlobalDoneHandler ( rpcDone ( & MainWidget : : updateReceived ) ) ;
2015-09-13 11:41:27 +03:00
_ptsWaiter . setRequesting ( true ) ;
2015-02-13 21:09:01 +03:00
updateScrollColors ( ) ;
2015-02-03 18:02:46 +03:00
2015-12-08 15:33:37 +03:00
connect ( App : : wnd ( ) , SIGNAL ( resized ( const QSize & ) ) , this , SLOT ( onParentResize ( const QSize & ) ) ) ;
2016-04-13 00:31:28 +03:00
connect ( _dialogs , SIGNAL ( cancelled ( ) ) , this , SLOT ( dialogsCancelled ( ) ) ) ;
connect ( _history , SIGNAL ( cancelled ( ) ) , _dialogs , SLOT ( activate ( ) ) ) ;
2015-01-26 16:04:41 +03:00
connect ( this , SIGNAL ( peerPhotoChanged ( PeerData * ) ) , this , SIGNAL ( dialogsUpdated ( ) ) ) ;
2015-04-16 17:59:42 +03:00
connect ( & noUpdatesTimer , SIGNAL ( timeout ( ) ) , this , SLOT ( mtpPing ( ) ) ) ;
2015-01-26 16:04:41 +03:00
connect ( & _onlineTimer , SIGNAL ( timeout ( ) ) , this , SLOT ( updateOnline ( ) ) ) ;
connect ( & _onlineUpdater , SIGNAL ( timeout ( ) ) , this , SLOT ( updateOnlineDisplay ( ) ) ) ;
connect ( & _idleFinishTimer , SIGNAL ( timeout ( ) ) , this , SLOT ( checkIdleFinish ( ) ) ) ;
2014-11-05 20:43:32 +03:00
connect ( & _bySeqTimer , SIGNAL ( timeout ( ) ) , this , SLOT ( getDifference ( ) ) ) ;
2015-09-13 11:41:27 +03:00
connect ( & _byPtsTimer , SIGNAL ( timeout ( ) ) , this , SLOT ( onGetDifferenceTimeByPts ( ) ) ) ;
2016-03-11 18:01:32 +03:00
connect ( & _byMinChannelTimer , SIGNAL ( timeout ( ) ) , this , SLOT ( getDifference ( ) ) ) ;
2015-09-13 11:41:27 +03:00
connect ( & _failDifferenceTimer , SIGNAL ( timeout ( ) ) , this , SLOT ( onGetDifferenceTimeAfterFail ( ) ) ) ;
2016-04-13 00:31:28 +03:00
connect ( _api . get ( ) , SIGNAL ( fullPeerUpdated ( PeerData * ) ) , this , SLOT ( onFullPeerUpdated ( PeerData * ) ) ) ;
connect ( this , SIGNAL ( peerUpdated ( PeerData * ) ) , _history , SLOT ( peerUpdated ( PeerData * ) ) ) ;
connect ( _topBar , SIGNAL ( clicked ( ) ) , this , SLOT ( onTopBarClick ( ) ) ) ;
connect ( _history , SIGNAL ( historyShown ( History * , MsgId ) ) , this , SLOT ( onHistoryShown ( History * , MsgId ) ) ) ;
2014-05-30 12:53:19 +04:00
connect ( & updateNotifySettingTimer , SIGNAL ( timeout ( ) ) , this , SLOT ( onUpdateNotifySettings ( ) ) ) ;
2015-05-29 21:52:43 +03:00
if ( audioPlayer ( ) ) {
2015-07-01 00:07:05 +03:00
connect ( audioPlayer ( ) , SIGNAL ( updated ( const AudioMsgId & ) ) , this , SLOT ( audioPlayProgress ( const AudioMsgId & ) ) ) ;
connect ( audioPlayer ( ) , SIGNAL ( stopped ( const AudioMsgId & ) ) , this , SLOT ( audioPlayProgress ( const AudioMsgId & ) ) ) ;
connect ( audioPlayer ( ) , SIGNAL ( updated ( const SongMsgId & ) ) , this , SLOT ( documentPlayProgress ( const SongMsgId & ) ) ) ;
connect ( audioPlayer ( ) , SIGNAL ( stopped ( const SongMsgId & ) ) , this , SLOT ( documentPlayProgress ( const SongMsgId & ) ) ) ;
2014-09-04 11:33:44 +04:00
}
2015-04-30 16:53:36 +03:00
connect ( & _updateMutedTimer , SIGNAL ( timeout ( ) ) , this , SLOT ( onUpdateMuted ( ) ) ) ;
2015-09-21 23:57:42 +03:00
connect ( & _viewsIncrementTimer , SIGNAL ( timeout ( ) ) , this , SLOT ( onViewsIncrement ( ) ) ) ;
2014-05-30 12:53:19 +04:00
2015-04-08 02:03:32 +03:00
_webPageUpdater . setSingleShot ( true ) ;
connect ( & _webPageUpdater , SIGNAL ( timeout ( ) ) , this , SLOT ( webPagesUpdate ( ) ) ) ;
2015-02-03 18:02:46 +03:00
connect ( & _cacheBackgroundTimer , SIGNAL ( timeout ( ) ) , this , SLOT ( onCacheBackground ( ) ) ) ;
2016-04-13 00:31:28 +03:00
_dialogs - > show ( ) ;
2016-02-08 17:54:55 +03:00
if ( Adaptive : : OneColumn ( ) ) {
2016-04-13 00:31:28 +03:00
_history - > hide ( ) ;
2016-02-08 17:54:55 +03:00
} else {
2016-04-13 00:31:28 +03:00
_history - > show ( ) ;
2014-12-12 19:27:03 +03:00
}
App : : wnd ( ) - > getTitle ( ) - > updateBackButton ( ) ;
2016-04-13 00:31:28 +03:00
_topBar - > hide ( ) ;
2014-05-30 12:53:19 +04:00
2016-04-14 19:08:36 +03:00
_player - > hidePlayer ( ) ;
2015-07-03 11:47:16 +03:00
2015-07-17 22:17:37 +03:00
orderWidgets ( ) ;
2014-05-30 12:53:19 +04:00
MTP : : setGlobalFailHandler ( rpcFail ( & MainWidget : : updateFail ) ) ;
2016-04-13 00:31:28 +03:00
_mediaType - > hide ( ) ;
_topBar - > mediaTypeButton ( ) - > installEventFilter ( _mediaType ) ;
2014-08-21 16:18:56 +04:00
2014-05-30 12:53:19 +04:00
show ( ) ;
setFocus ( ) ;
2015-03-02 15:34:16 +03:00
2015-03-19 12:18:19 +03:00
_api - > init ( ) ;
2016-04-14 22:24:42 +03:00
# ifndef TDESKTOP_DISABLE_AUTOUPDATE
Sandbox : : startUpdateCheck ( ) ;
# endif
2014-05-30 12:53:19 +04:00
}
2015-09-07 10:52:37 +03:00
bool MainWidget : : onForward ( const PeerId & peer , ForwardWhatMessages what ) {
PeerData * p = App : : peer ( peer ) ;
2015-11-06 12:48:49 -05:00
if ( ! peer | | ( p - > isChannel ( ) & & ! p - > asChannel ( ) - > canPublish ( ) & & p - > asChannel ( ) - > isBroadcast ( ) ) | | ( p - > isChat ( ) & & ! p - > asChat ( ) - > canWrite ( ) ) | | ( p - > isUser ( ) & & p - > asUser ( ) - > access = = UserNoAccess ) ) {
2015-12-07 21:09:05 +03:00
Ui : : showLayer ( new InformBox ( lang ( lng_forward_cant ) ) ) ;
2015-09-07 10:52:37 +03:00
return false ;
}
2016-04-13 00:31:28 +03:00
_history - > cancelReply ( ) ;
2015-03-24 13:00:27 +03:00
_toForward . clear ( ) ;
2015-06-27 16:02:00 +03:00
if ( what = = ForwardSelectedMessages ) {
2016-04-13 00:31:28 +03:00
if ( _overview ) {
_overview - > fillSelectedItems ( _toForward , false ) ;
2014-08-20 09:32:50 +04:00
} else {
2016-04-13 00:31:28 +03:00
_history - > fillSelectedItems ( _toForward , false ) ;
2014-08-20 09:32:50 +04:00
}
2015-06-27 16:02:00 +03:00
} else {
HistoryItem * item = 0 ;
if ( what = = ForwardContextMessage ) {
item = App : : contextItem ( ) ;
} else if ( what = = ForwardPressedMessage ) {
item = App : : pressedItem ( ) ;
} else if ( what = = ForwardPressedLinkMessage ) {
item = App : : pressedLinkItem ( ) ;
}
2015-11-13 18:14:33 +03:00
if ( item & & item - > toHistoryMessage ( ) & & item - > id > 0 ) {
2015-06-27 16:02:00 +03:00
_toForward . insert ( item - > id , item ) ;
}
2015-03-24 13:00:27 +03:00
}
updateForwardingTexts ( ) ;
2015-12-13 14:36:08 +03:00
Ui : : showPeerHistory ( peer , ShowAtUnreadMsgId ) ;
2016-04-13 00:31:28 +03:00
_history - > onClearSelected ( ) ;
_history - > updateForwarding ( ) ;
2015-09-07 10:52:37 +03:00
return true ;
2015-03-24 13:00:27 +03:00
}
2015-10-18 14:49:34 +02:00
bool MainWidget : : onShareUrl ( const PeerId & peer , const QString & url , const QString & text ) {
PeerData * p = App : : peer ( peer ) ;
2015-11-06 12:48:49 -05:00
if ( ! peer | | ( p - > isChannel ( ) & & ! p - > asChannel ( ) - > canPublish ( ) & & p - > asChannel ( ) - > isBroadcast ( ) ) | | ( p - > isChat ( ) & & ! p - > asChat ( ) - > canWrite ( ) ) | | ( p - > isUser ( ) & & p - > asUser ( ) - > access = = UserNoAccess ) ) {
2015-12-07 21:09:05 +03:00
Ui : : showLayer ( new InformBox ( lang ( lng_share_cant ) ) ) ;
2015-10-18 14:49:34 +02:00
return false ;
}
History * h = App : : history ( peer ) ;
2016-05-05 19:04:17 +03:00
TextWithTags textWithTags = { url + ' \n ' + text , TextWithTags : : Tags ( ) } ;
MessageCursor cursor = { url . size ( ) + 1 , url . size ( ) + 1 + text . size ( ) , QFIXED_MAX } ;
h - > setMsgDraft ( std_ : : make_unique < HistoryDraft > ( textWithTags , 0 , cursor , false ) ) ;
2016-04-08 18:16:52 +04:00
h - > clearEditDraft ( ) ;
2016-04-13 00:31:28 +03:00
bool opened = _history - > peer ( ) & & ( _history - > peer ( ) - > id = = peer ) ;
2016-04-08 18:16:52 +04:00
if ( opened ) {
2016-04-13 00:31:28 +03:00
_history - > applyDraft ( ) ;
2016-04-08 18:16:52 +04:00
} else {
Ui : : showPeerHistory ( peer , ShowAtUnreadMsgId ) ;
}
return true ;
}
bool MainWidget : : onInlineSwitchChosen ( const PeerId & peer , const QString & botAndQuery ) {
PeerData * p = App : : peer ( peer ) ;
if ( ! peer | | ( p - > isChannel ( ) & & ! p - > asChannel ( ) - > canPublish ( ) & & p - > asChannel ( ) - > isBroadcast ( ) ) | | ( p - > isChat ( ) & & ! p - > asChat ( ) - > canWrite ( ) ) | | ( p - > isUser ( ) & & p - > asUser ( ) - > access = = UserNoAccess ) ) {
Ui : : showLayer ( new InformBox ( lang ( lng_inline_switch_cant ) ) ) ;
return false ;
}
History * h = App : : history ( peer ) ;
2016-05-05 19:04:17 +03:00
TextWithTags textWithTags = { botAndQuery , TextWithTags : : Tags ( ) } ;
MessageCursor cursor = { botAndQuery . size ( ) , botAndQuery . size ( ) , QFIXED_MAX } ;
h - > setMsgDraft ( std_ : : make_unique < HistoryDraft > ( textWithTags , 0 , cursor , false ) ) ;
2016-04-08 18:16:52 +04:00
h - > clearEditDraft ( ) ;
2016-04-13 00:31:28 +03:00
bool opened = _history - > peer ( ) & & ( _history - > peer ( ) - > id = = peer ) ;
2015-10-18 14:49:34 +02:00
if ( opened ) {
2016-04-13 00:31:28 +03:00
_history - > applyDraft ( ) ;
2015-10-18 14:49:34 +02:00
} else {
2015-12-13 14:36:08 +03:00
Ui : : showPeerHistory ( peer , ShowAtUnreadMsgId ) ;
2015-10-18 14:49:34 +02:00
}
return true ;
}
2015-03-24 13:00:27 +03:00
bool MainWidget : : hasForwardingItems ( ) {
return ! _toForward . isEmpty ( ) ;
}
void MainWidget : : fillForwardingInfo ( Text * & from , Text * & text , bool & serviceColor , ImagePtr & preview ) {
if ( _toForward . isEmpty ( ) ) return ;
int32 version = 0 ;
for ( SelectedItemSet : : const_iterator i = _toForward . cbegin ( ) , e = _toForward . cend ( ) ; i ! = e ; + + i ) {
2016-02-18 22:12:50 +03:00
version + = i . value ( ) - > authorOriginal ( ) - > nameVersion ;
2015-03-24 13:00:27 +03:00
}
if ( version ! = _toForwardNameVersion ) {
updateForwardingTexts ( ) ;
}
from = & _toForwardFrom ;
text = & _toForwardText ;
serviceColor = ( _toForward . size ( ) > 1 ) | | _toForward . cbegin ( ) . value ( ) - > getMedia ( ) | | _toForward . cbegin ( ) . value ( ) - > serviceMsg ( ) ;
if ( _toForward . size ( ) < 2 & & _toForward . cbegin ( ) . value ( ) - > getMedia ( ) & & _toForward . cbegin ( ) . value ( ) - > getMedia ( ) - > hasReplyPreview ( ) ) {
preview = _toForward . cbegin ( ) . value ( ) - > getMedia ( ) - > replyPreview ( ) ;
}
}
void MainWidget : : updateForwardingTexts ( ) {
int32 version = 0 ;
QString from , text ;
if ( ! _toForward . isEmpty ( ) ) {
2015-09-04 16:01:31 +03:00
QMap < PeerData * , bool > fromUsersMap ;
QVector < PeerData * > fromUsers ;
2015-03-24 13:00:27 +03:00
fromUsers . reserve ( _toForward . size ( ) ) ;
for ( SelectedItemSet : : const_iterator i = _toForward . cbegin ( ) , e = _toForward . cend ( ) ; i ! = e ; + + i ) {
2016-02-18 22:12:50 +03:00
PeerData * from = i . value ( ) - > authorOriginal ( ) ;
2015-10-29 11:27:34 -04:00
if ( ! fromUsersMap . contains ( from ) ) {
fromUsersMap . insert ( from , true ) ;
fromUsers . push_back ( from ) ;
2015-03-24 13:00:27 +03:00
}
2016-02-17 19:37:21 +03:00
version + = from - > nameVersion ;
2015-03-24 13:00:27 +03:00
}
if ( fromUsers . size ( ) > 2 ) {
2015-09-04 16:01:31 +03:00
from = lng_forwarding_from ( lt_user , fromUsers . at ( 0 ) - > shortName ( ) , lt_count , fromUsers . size ( ) - 1 ) ;
2015-03-24 13:00:27 +03:00
} else if ( fromUsers . size ( ) < 2 ) {
from = fromUsers . at ( 0 ) - > name ;
} else {
2015-09-04 16:01:31 +03:00
from = lng_forwarding_from_two ( lt_user , fromUsers . at ( 0 ) - > shortName ( ) , lt_second_user , fromUsers . at ( 1 ) - > shortName ( ) ) ;
2015-03-24 13:00:27 +03:00
}
if ( _toForward . size ( ) < 2 ) {
text = _toForward . cbegin ( ) . value ( ) - > inReplyText ( ) ;
} else {
text = lng_forward_messages ( lt_count , _toForward . size ( ) ) ;
}
}
_toForwardFrom . setText ( st : : msgServiceNameFont , from , _textNameOptions ) ;
_toForwardText . setText ( st : : msgFont , text , _textDlgOptions ) ;
_toForwardNameVersion = version ;
}
void MainWidget : : cancelForwarding ( ) {
if ( _toForward . isEmpty ( ) ) return ;
_toForward . clear ( ) ;
2016-04-13 00:31:28 +03:00
_history - > cancelForwarding ( ) ;
2015-03-24 13:00:27 +03:00
}
2016-02-25 19:19:54 +03:00
void MainWidget : : finishForwarding ( History * hist , bool broadcast , bool silent ) {
2015-04-04 23:01:34 +03:00
if ( ! hist ) return ;
2015-12-31 23:27:21 +08:00
2015-04-04 23:01:34 +03:00
if ( ! _toForward . isEmpty ( ) ) {
2015-09-12 14:59:50 +03:00
bool genClientSideMessage = ( _toForward . size ( ) < 2 ) ;
2015-11-13 18:14:33 +03:00
PeerData * forwardFrom = 0 ;
2015-04-04 23:01:34 +03:00
App : : main ( ) - > readServerHistory ( hist , false ) ;
2015-09-12 14:59:50 +03:00
2016-03-19 19:55:15 +03:00
MTPDmessage : : Flags flags = 0 ;
MTPmessages_ForwardMessages : : Flags sendFlags = 0 ;
2016-02-17 19:37:21 +03:00
bool channelPost = hist - > peer - > isChannel ( ) & & ! hist - > peer - > isMegagroup ( ) & & hist - > peer - > asChannel ( ) - > canPublish ( ) & & ( hist - > peer - > asChannel ( ) - > isBroadcast ( ) | | broadcast ) ;
bool showFromName = ! channelPost | | hist - > peer - > asChannel ( ) - > addsSignature ( ) ;
2016-02-25 19:19:54 +03:00
bool silentPost = channelPost & & silent ;
2016-02-17 19:37:21 +03:00
if ( channelPost ) {
2016-03-19 19:55:15 +03:00
sendFlags | = MTPmessages_ForwardMessages : : Flag : : f_broadcast ;
flags | = MTPDmessage : : Flag : : f_views ;
flags | = MTPDmessage : : Flag : : f_post ;
2016-02-17 19:37:21 +03:00
}
if ( showFromName ) {
2016-03-19 19:55:15 +03:00
flags | = MTPDmessage : : Flag : : f_from_id ;
2016-02-17 19:37:21 +03:00
}
2016-02-25 19:19:54 +03:00
if ( silentPost ) {
2016-03-19 19:55:15 +03:00
sendFlags | = MTPmessages_ForwardMessages : : Flag : : f_silent ;
2016-02-25 19:19:54 +03:00
}
2015-11-13 18:14:33 +03:00
2015-09-12 14:59:50 +03:00
QVector < MTPint > ids ;
QVector < MTPlong > randomIds ;
ids . reserve ( _toForward . size ( ) ) ;
randomIds . reserve ( _toForward . size ( ) ) ;
for ( SelectedItemSet : : const_iterator i = _toForward . cbegin ( ) , e = _toForward . cend ( ) ; i ! = e ; + + i ) {
2016-03-24 13:12:18 +03:00
uint64 randomId = rand_value < uint64 > ( ) ;
2015-09-12 14:59:50 +03:00
if ( genClientSideMessage ) {
FullMsgId newId ( peerToChannel ( hist - > peer - > id ) , clientMsgId ( ) ) ;
HistoryMessage * msg = static_cast < HistoryMessage * > ( _toForward . cbegin ( ) . value ( ) ) ;
2016-02-17 19:37:21 +03:00
hist - > addNewForwarded ( newId . msg , flags , date ( MTP_int ( unixtime ( ) ) ) , showFromName ? MTP : : authedId ( ) : 0 , msg ) ;
2015-12-23 15:19:32 +03:00
if ( HistoryMedia * media = msg - > getMedia ( ) ) {
if ( media - > type ( ) = = MediaTypeSticker ) {
App : : main ( ) - > incrementSticker ( media - > getDocument ( ) ) ;
}
2015-09-12 14:59:50 +03:00
}
App : : historyRegRandom ( randomId , newId ) ;
2015-04-04 23:01:34 +03:00
}
2015-11-13 18:14:33 +03:00
if ( forwardFrom ! = i . value ( ) - > history ( ) - > peer ) {
if ( forwardFrom ) {
2016-03-19 19:55:15 +03:00
hist - > sendRequestId = MTP : : send ( MTPmessages_ForwardMessages ( MTP_flags ( sendFlags ) , forwardFrom - > input , MTP_vector < MTPint > ( ids ) , MTP_vector < MTPlong > ( randomIds ) , hist - > peer - > input ) , rpcDone ( & MainWidget : : sentUpdatesReceived ) , RPCFailHandlerPtr ( ) , 0 , 0 , hist - > sendRequestId ) ;
2015-11-13 18:14:33 +03:00
ids . resize ( 0 ) ;
randomIds . resize ( 0 ) ;
}
forwardFrom = i . value ( ) - > history ( ) - > peer ;
}
ids . push_back ( MTP_int ( i . value ( ) - > id ) ) ;
2015-09-12 14:59:50 +03:00
randomIds . push_back ( MTP_long ( randomId ) ) ;
2014-08-20 09:32:50 +04:00
}
2016-03-19 19:55:15 +03:00
hist - > sendRequestId = MTP : : send ( MTPmessages_ForwardMessages ( MTP_flags ( sendFlags ) , forwardFrom - > input , MTP_vector < MTPint > ( ids ) , MTP_vector < MTPlong > ( randomIds ) , hist - > peer - > input ) , rpcDone ( & MainWidget : : sentUpdatesReceived ) , RPCFailHandlerPtr ( ) , 0 , 0 , hist - > sendRequestId ) ;
2015-09-12 14:59:50 +03:00
2016-04-13 00:31:28 +03:00
if ( _history - > peer ( ) = = hist - > peer ) {
_history - > peerMessagesUpdated ( ) ;
2015-11-13 18:14:33 +03:00
}
2015-09-12 14:59:50 +03:00
2015-04-04 23:01:34 +03:00
cancelForwarding ( ) ;
2014-08-20 09:32:50 +04:00
}
2015-04-04 23:01:34 +03:00
historyToDown ( hist ) ;
dialogsToUp ( ) ;
2016-04-13 00:31:28 +03:00
_history - > peerMessagesUpdated ( hist - > peer - > id ) ;
2014-05-30 12:53:19 +04:00
}
2015-04-08 02:03:32 +03:00
void MainWidget : : webPageUpdated ( WebPageData * data ) {
_webPagesUpdated . insert ( data - > id , true ) ;
_webPageUpdater . start ( 0 ) ;
}
void MainWidget : : webPagesUpdate ( ) {
2015-04-30 16:53:36 +03:00
if ( _webPagesUpdated . isEmpty ( ) ) return ;
_webPageUpdater . stop ( ) ;
2015-04-08 02:03:32 +03:00
const WebPageItems & items ( App : : webPageItems ( ) ) ;
for ( QMap < WebPageId , bool > : : const_iterator i = _webPagesUpdated . cbegin ( ) , e = _webPagesUpdated . cend ( ) ; i ! = e ; + + i ) {
WebPageItems : : const_iterator j = items . constFind ( App : : webPage ( i . key ( ) ) ) ;
if ( j ! = items . cend ( ) ) {
for ( HistoryItemsMap : : const_iterator k = j . value ( ) . cbegin ( ) , e = j . value ( ) . cend ( ) ; k ! = e ; + + k ) {
2016-03-19 19:55:15 +03:00
k . key ( ) - > setPendingInitDimensions ( ) ;
2015-04-08 02:03:32 +03:00
}
}
}
_webPagesUpdated . clear ( ) ;
}
2015-04-30 16:53:36 +03:00
void MainWidget : : updateMutedIn ( int32 seconds ) {
if ( seconds > 86400 ) seconds = 86400 ;
int32 ms = seconds * 1000 ;
if ( _updateMutedTimer . isActive ( ) & & _updateMutedTimer . remainingTime ( ) < = ms ) return ;
_updateMutedTimer . start ( ms ) ;
}
2015-05-19 18:46:45 +03:00
void MainWidget : : updateStickers ( ) {
2016-04-13 00:31:28 +03:00
_history - > updateStickers ( ) ;
2015-05-19 18:46:45 +03:00
}
2015-04-30 16:53:36 +03:00
void MainWidget : : onUpdateMuted ( ) {
App : : updateMuted ( ) ;
}
2014-05-30 12:53:19 +04:00
void MainWidget : : onShareContact ( const PeerId & peer , UserData * contact ) {
2016-04-13 00:31:28 +03:00
_history - > onShareContact ( peer , contact ) ;
2014-05-30 12:53:19 +04:00
}
2014-07-18 14:37:34 +04:00
void MainWidget : : onSendPaths ( const PeerId & peer ) {
2016-04-13 00:31:28 +03:00
_history - > onSendPaths ( peer ) ;
2014-07-18 14:37:34 +04:00
}
2015-06-27 16:02:00 +03:00
void MainWidget : : onFilesOrForwardDrop ( const PeerId & peer , const QMimeData * data ) {
if ( data - > hasFormat ( qsl ( " application/x-td-forward-selected " ) ) ) {
onForward ( peer , ForwardSelectedMessages ) ;
} else if ( data - > hasFormat ( qsl ( " application/x-td-forward-pressed-link " ) ) ) {
onForward ( peer , ForwardPressedLinkMessage ) ;
} else if ( data - > hasFormat ( qsl ( " application/x-td-forward-pressed " ) ) ) {
onForward ( peer , ForwardPressedMessage ) ;
} else {
2015-12-13 14:36:08 +03:00
Ui : : showPeerHistory ( peer , ShowAtTheEndMsgId ) ;
2016-04-13 00:31:28 +03:00
_history - > onFilesDrop ( data ) ;
2015-06-27 16:02:00 +03:00
}
2015-06-26 12:07:59 +03:00
}
2016-04-09 15:02:50 +04:00
void MainWidget : : rpcClear ( ) {
2016-04-13 00:31:28 +03:00
_history - > rpcClear ( ) ;
_dialogs - > rpcClear ( ) ;
if ( _overview ) _overview - > rpcClear ( ) ;
2016-04-09 15:02:50 +04:00
if ( _api ) _api - > rpcClear ( ) ;
RPCSender : : rpcClear ( ) ;
}
2015-10-17 16:52:26 +02:00
QPixmap MainWidget : : grabInner ( ) {
2016-04-13 00:31:28 +03:00
if ( _overview & & ! _overview - > isHidden ( ) ) {
return myGrab ( _overview ) ;
2016-05-19 15:03:51 +03:00
} else if ( _wideSection & & ! _wideSection - > isHidden ( ) ) {
return myGrab ( _wideSection , QRect ( 0 , st : : topBarHeight , _history - > width ( ) , _history - > height ( ) - st : : topBarHeight ) ) ;
2016-04-13 00:31:28 +03:00
} else if ( Adaptive : : OneColumn ( ) & & _history - > isHidden ( ) ) {
return myGrab ( _dialogs , QRect ( 0 , st : : topBarHeight , _dialogs - > width ( ) , _dialogs - > height ( ) - st : : topBarHeight ) ) ;
} else if ( _history - > peer ( ) ) {
return myGrab ( _history ) ;
2015-10-17 16:52:26 +02:00
} else {
2016-04-13 00:31:28 +03:00
return myGrab ( _history , QRect ( 0 , st : : topBarHeight , _history - > width ( ) , _history - > height ( ) - st : : topBarHeight ) ) ;
2015-10-17 16:52:26 +02:00
}
}
2015-12-23 19:48:44 +03:00
bool MainWidget : : isItemVisible ( HistoryItem * item ) {
if ( isHidden ( ) | | _a_show . animating ( ) ) {
return false ;
}
2016-04-13 00:31:28 +03:00
return _history - > isItemVisible ( item ) ;
2015-12-23 19:48:44 +03:00
}
2015-10-17 16:52:26 +02:00
QPixmap MainWidget : : grabTopBar ( ) {
2016-04-13 00:31:28 +03:00
if ( ! _topBar - > isHidden ( ) ) {
return myGrab ( _topBar ) ;
2016-05-19 15:03:51 +03:00
} else if ( _wideSection ) {
return myGrab ( _wideSection , QRect ( 0 , 0 , _wideSection - > width ( ) , st : : topBarHeight ) ) ;
2016-04-13 00:31:28 +03:00
} else if ( Adaptive : : OneColumn ( ) & & _history - > isHidden ( ) ) {
return myGrab ( _dialogs , QRect ( 0 , 0 , _dialogs - > width ( ) , st : : topBarHeight ) ) ;
2015-10-17 16:52:26 +02:00
} else {
2016-04-13 00:31:28 +03:00
return myGrab ( _history , QRect ( 0 , 0 , _history - > width ( ) , st : : topBarHeight ) ) ;
2015-10-17 16:52:26 +02:00
}
}
2015-12-11 21:11:38 +03:00
void MainWidget : : notify_botCommandsChanged ( UserData * bot ) {
2016-04-13 00:31:28 +03:00
_history - > notify_botCommandsChanged ( bot ) ;
2015-12-11 21:11:38 +03:00
}
2016-01-01 17:58:05 +08:00
void MainWidget : : notify_inlineBotRequesting ( bool requesting ) {
2016-04-13 00:31:28 +03:00
_history - > notify_inlineBotRequesting ( requesting ) ;
2016-01-01 17:58:05 +08:00
}
2016-04-01 19:32:26 +04:00
void MainWidget : : notify_replyMarkupUpdated ( const HistoryItem * item ) {
2016-04-13 00:31:28 +03:00
_history - > notify_replyMarkupUpdated ( item ) ;
2016-04-01 19:32:26 +04:00
}
2016-04-08 13:20:10 +04:00
void MainWidget : : notify_inlineKeyboardMoved ( const HistoryItem * item , int oldKeyboardTop , int newKeyboardTop ) {
2016-04-13 00:31:28 +03:00
_history - > notify_inlineKeyboardMoved ( item , oldKeyboardTop , newKeyboardTop ) ;
2016-04-08 13:20:10 +04:00
}
2016-04-11 00:59:07 +04:00
bool MainWidget : : notify_switchInlineBotButtonReceived ( const QString & query ) {
2016-04-13 00:31:28 +03:00
return _history - > notify_switchInlineBotButtonReceived ( query ) ;
2016-04-08 18:16:52 +04:00
}
2015-12-11 21:11:38 +03:00
void MainWidget : : notify_userIsBotChanged ( UserData * bot ) {
2016-04-13 00:31:28 +03:00
_history - > notify_userIsBotChanged ( bot ) ;
2015-12-11 21:11:38 +03:00
}
2015-12-13 14:17:15 +03:00
void MainWidget : : notify_userIsContactChanged ( UserData * user , bool fromThisApp ) {
if ( ! user ) return ;
2016-04-13 00:31:28 +03:00
_dialogs - > notify_userIsContactChanged ( user , fromThisApp ) ;
2015-12-13 14:17:15 +03:00
const SharedContactItems & items ( App : : sharedContactItems ( ) ) ;
SharedContactItems : : const_iterator i = items . constFind ( peerToUser ( user - > id ) ) ;
if ( i ! = items . cend ( ) ) {
for ( HistoryItemsMap : : const_iterator j = i - > cbegin ( ) , e = i - > cend ( ) ; j ! = e ; + + j ) {
2016-03-19 19:55:15 +03:00
j . key ( ) - > setPendingInitDimensions ( ) ;
2015-12-13 14:17:15 +03:00
}
}
if ( user - > contact > 0 & & fromThisApp ) {
Ui : : showPeerHistory ( user - > id , ShowAtTheEndMsgId ) ;
}
}
2015-12-11 21:11:38 +03:00
void MainWidget : : notify_migrateUpdated ( PeerData * peer ) {
2016-04-13 00:31:28 +03:00
_history - > notify_migrateUpdated ( peer ) ;
2015-12-11 21:11:38 +03:00
}
2015-12-28 00:37:48 +03:00
void MainWidget : : notify_clipStopperHidden ( ClipStopperType type ) {
2016-04-13 00:31:28 +03:00
_history - > notify_clipStopperHidden ( type ) ;
2015-12-25 16:09:14 +03:00
}
2015-12-28 00:37:48 +03:00
void MainWidget : : ui_repaintHistoryItem ( const HistoryItem * item ) {
2016-04-13 00:31:28 +03:00
_history - > ui_repaintHistoryItem ( item ) ;
2016-02-28 14:58:30 +03:00
if ( item - > history ( ) - > lastMsg = = item ) {
item - > history ( ) - > updateChatListEntry ( ) ;
2015-12-11 21:11:38 +03:00
}
2016-04-13 00:31:28 +03:00
if ( _overview ) _overview - > ui_repaintHistoryItem ( item ) ;
2015-12-28 00:37:48 +03:00
}
2016-04-05 01:09:46 +04:00
void MainWidget : : ui_repaintInlineItem ( const InlineBots : : Layout : : ItemBase * layout ) {
2016-04-13 00:31:28 +03:00
_history - > ui_repaintInlineItem ( layout ) ;
2015-12-28 00:37:48 +03:00
}
2016-04-05 01:09:46 +04:00
bool MainWidget : : ui_isInlineItemVisible ( const InlineBots : : Layout : : ItemBase * layout ) {
2016-04-13 00:31:28 +03:00
return _history - > ui_isInlineItemVisible ( layout ) ;
2015-12-28 00:37:48 +03:00
}
2015-12-31 03:09:20 +08:00
bool MainWidget : : ui_isInlineItemBeingChosen ( ) {
2016-04-13 00:31:28 +03:00
return _history - > ui_isInlineItemBeingChosen ( ) ;
2015-12-13 01:29:33 +03:00
}
void MainWidget : : notify_historyItemLayoutChanged ( const HistoryItem * item ) {
2016-04-13 00:31:28 +03:00
_history - > notify_historyItemLayoutChanged ( item ) ;
if ( _overview ) _overview - > notify_historyItemLayoutChanged ( item ) ;
2015-12-11 21:11:38 +03:00
}
2016-04-10 22:18:26 +04:00
void MainWidget : : notify_inlineItemLayoutChanged ( const InlineBots : : Layout : : ItemBase * layout ) {
2016-04-13 00:31:28 +03:00
_history - > notify_inlineItemLayoutChanged ( layout ) ;
2016-04-10 22:18:26 +04:00
}
2016-04-11 14:59:01 +04:00
void MainWidget : : notify_historyMuteUpdated ( History * history ) {
2016-04-13 00:31:28 +03:00
_dialogs - > notify_historyMuteUpdated ( history ) ;
2016-04-11 14:59:01 +04:00
}
2016-03-19 19:55:15 +03:00
void MainWidget : : notify_handlePendingHistoryUpdate ( ) {
2016-04-13 00:31:28 +03:00
_history - > notify_handlePendingHistoryUpdate ( ) ;
2016-03-19 19:55:15 +03:00
}
2016-02-27 22:39:51 +03:00
void MainWidget : : cmd_search ( ) {
2016-04-13 00:31:28 +03:00
_history - > cmd_search ( ) ;
2016-02-27 22:39:51 +03:00
}
void MainWidget : : cmd_next_chat ( ) {
2016-04-13 00:31:28 +03:00
_history - > cmd_next_chat ( ) ;
2016-02-27 22:39:51 +03:00
}
void MainWidget : : cmd_previous_chat ( ) {
2016-04-13 00:31:28 +03:00
_history - > cmd_previous_chat ( ) ;
2016-02-27 22:39:51 +03:00
}
2014-05-30 12:53:19 +04:00
void MainWidget : : noHider ( HistoryHider * destroyed ) {
2015-07-17 22:17:37 +03:00
if ( _hider = = destroyed ) {
2016-04-13 00:31:28 +03:00
_hider = nullptr ;
2016-02-08 17:54:55 +03:00
if ( Adaptive : : OneColumn ( ) ) {
2014-12-12 19:27:03 +03:00
if ( _forwardConfirm ) {
_forwardConfirm - > startHide ( ) ;
_forwardConfirm = 0 ;
}
2016-04-13 00:31:28 +03:00
onHistoryShown ( _history - > history ( ) , _history - > msgId ( ) ) ;
2016-05-19 15:03:51 +03:00
if ( _wideSection | | _overview | | ( _history - > peer ( ) & & _history - > peer ( ) - > id ) ) {
Window : : SectionSlideParams animationParams ;
if ( _overview ) {
animationParams = prepareOverviewAnimation ( ) ;
} else if ( _wideSection ) {
animationParams = prepareWideSectionAnimation ( _wideSection ) ;
2016-05-12 19:05:20 +03:00
} else {
2016-05-19 15:03:51 +03:00
animationParams = prepareHistoryAnimation ( _history - > peer ( ) ? _history - > peer ( ) - > id : 0 ) ;
2016-05-12 19:05:20 +03:00
}
2016-04-13 00:31:28 +03:00
_dialogs - > hide ( ) ;
if ( _overview ) {
2016-05-19 15:03:51 +03:00
_overview - > showAnimated ( Window : : SlideDirection : : FromRight , animationParams ) ;
} else if ( _wideSection ) {
_wideSection - > showAnimated ( Window : : SlideDirection : : FromRight , animationParams ) ;
2014-12-12 19:27:03 +03:00
} else {
2016-05-19 15:03:51 +03:00
_history - > showAnimated ( Window : : SlideDirection : : FromRight , animationParams ) ;
2014-12-12 19:27:03 +03:00
}
}
App : : wnd ( ) - > getTitle ( ) - > updateBackButton ( ) ;
2016-02-08 17:54:55 +03:00
} else {
if ( _forwardConfirm ) {
_forwardConfirm - > deleteLater ( ) ;
_forwardConfirm = 0 ;
}
2014-12-12 19:27:03 +03:00
}
2014-05-30 12:53:19 +04:00
}
}
2014-12-12 19:27:03 +03:00
void MainWidget : : hiderLayer ( HistoryHider * h ) {
2015-04-04 23:01:34 +03:00
if ( App : : passcoded ( ) ) {
delete h ;
return ;
}
2015-03-02 15:34:16 +03:00
2015-07-17 22:17:37 +03:00
_hider = h ;
2016-04-13 00:31:28 +03:00
connect ( _hider , SIGNAL ( forwarded ( ) ) , _dialogs , SLOT ( onCancelSearch ( ) ) ) ;
2016-02-08 17:54:55 +03:00
if ( Adaptive : : OneColumn ( ) ) {
2015-06-26 12:07:59 +03:00
dialogsToUp ( ) ;
2015-07-17 22:17:37 +03:00
_hider - > hide ( ) ;
2016-05-19 15:03:51 +03:00
auto animationParams = prepareDialogsAnimation ( ) ;
2014-12-12 19:27:03 +03:00
2015-10-03 13:09:09 +03:00
onHistoryShown ( 0 , 0 ) ;
2016-04-13 00:31:28 +03:00
if ( _overview ) {
_overview - > hide ( ) ;
2016-05-19 15:03:51 +03:00
} else if ( _wideSection ) {
_wideSection - > hide ( ) ;
2014-12-12 19:27:03 +03:00
} else {
2016-04-13 00:31:28 +03:00
_history - > hide ( ) ;
2014-12-12 19:27:03 +03:00
}
2016-04-13 00:31:28 +03:00
_dialogs - > show ( ) ;
2014-12-12 19:27:03 +03:00
resizeEvent ( 0 ) ;
2016-05-19 15:03:51 +03:00
_dialogs - > showAnimated ( Window : : SlideDirection : : FromLeft , animationParams ) ;
2014-12-12 19:27:03 +03:00
App : : wnd ( ) - > getTitle ( ) - > updateBackButton ( ) ;
2016-02-08 17:54:55 +03:00
} else {
_hider - > show ( ) ;
resizeEvent ( 0 ) ;
2016-04-13 00:31:28 +03:00
_dialogs - > activate ( ) ;
2014-12-12 19:27:03 +03:00
}
}
void MainWidget : : forwardLayer ( int32 forwardSelected ) {
hiderLayer ( ( forwardSelected < 0 ) ? ( new HistoryHider ( this ) ) : ( new HistoryHider ( this , forwardSelected > 0 ) ) ) ;
2014-05-30 12:53:19 +04:00
}
void MainWidget : : deleteLayer ( int32 selectedCount ) {
2016-04-13 00:31:28 +03:00
if ( selectedCount = = - 1 & & ! _overview ) {
2016-03-14 19:59:18 +03:00
if ( HistoryItem * item = App : : contextItem ( ) ) {
2016-03-13 18:45:00 +03:00
if ( item - > suggestBanReportDeleteAll ( ) ) {
Ui : : showLayer ( new RichDeleteMessageBox ( item - > history ( ) - > peer - > asChannel ( ) , item - > from ( ) - > asUser ( ) , item - > id ) ) ;
2016-03-10 18:42:01 +03:00
return ;
}
}
}
2014-12-18 21:40:49 +03:00
QString str ( ( selectedCount < 0 ) ? lang ( selectedCount < - 1 ? lng_selected_cancel_sure_this : lng_selected_delete_sure_this ) : lng_selected_delete_sure ( lt_count , selectedCount ) ) ;
2016-01-07 17:49:54 +08:00
QString btn ( lang ( ( selectedCount < - 1 ) ? lng_selected_upload_stop : lng_box_delete ) ) , cancel ( lang ( ( selectedCount < - 1 ) ? lng_continue : lng_cancel ) ) ;
ConfirmBox * box = new ConfirmBox ( str , btn , st : : defaultBoxButton , cancel ) ;
2014-05-30 12:53:19 +04:00
if ( selectedCount < 0 ) {
2015-12-24 22:26:28 +03:00
if ( selectedCount < - 1 ) {
if ( HistoryItem * item = App : : contextItem ( ) ) {
App : : uploader ( ) - > pause ( item - > fullId ( ) ) ;
connect ( box , SIGNAL ( destroyed ( QObject * ) ) , App : : uploader ( ) , SLOT ( unpause ( ) ) ) ;
}
}
2016-04-13 00:31:28 +03:00
connect ( box , SIGNAL ( confirmed ( ) ) , _overview ? static_cast < QWidget * > ( _overview ) : static_cast < QWidget * > ( _history ) , SLOT ( onDeleteContextSure ( ) ) ) ;
2014-05-30 12:53:19 +04:00
} else {
2016-04-13 00:31:28 +03:00
connect ( box , SIGNAL ( confirmed ( ) ) , _overview ? static_cast < QWidget * > ( _overview ) : static_cast < QWidget * > ( _history ) , SLOT ( onDeleteSelectedSure ( ) ) ) ;
2014-05-30 12:53:19 +04:00
}
2015-12-07 21:09:05 +03:00
Ui : : showLayer ( box ) ;
2014-05-30 12:53:19 +04:00
}
void MainWidget : : shareContactLayer ( UserData * contact ) {
2014-12-12 19:27:03 +03:00
hiderLayer ( new HistoryHider ( this , contact ) ) ;
2014-05-30 12:53:19 +04:00
}
2015-10-18 14:49:34 +02:00
void MainWidget : : shareUrlLayer ( const QString & url , const QString & text ) {
hiderLayer ( new HistoryHider ( this , url , text ) ) ;
}
2016-04-08 18:16:52 +04:00
void MainWidget : : inlineSwitchLayer ( const QString & botAndQuery ) {
hiderLayer ( new HistoryHider ( this , botAndQuery ) ) ;
}
2015-04-04 23:01:34 +03:00
bool MainWidget : : selectingPeer ( bool withConfirm ) {
2015-07-17 22:17:37 +03:00
return _hider ? ( withConfirm ? _hider - > withConfirm ( ) : true ) : false ;
2014-05-30 12:53:19 +04:00
}
2016-04-08 18:16:52 +04:00
bool MainWidget : : selectingPeerForInlineSwitch ( ) {
return selectingPeer ( ) ? ! _hider - > botAndQuery ( ) . isEmpty ( ) : false ;
}
2014-05-30 12:53:19 +04:00
void MainWidget : : offerPeer ( PeerId peer ) {
2015-12-07 21:09:05 +03:00
Ui : : hideLayer ( ) ;
2016-02-08 17:54:55 +03:00
if ( _hider - > offerPeer ( peer ) & & Adaptive : : OneColumn ( ) ) {
2015-10-03 13:09:09 +03:00
_forwardConfirm = new ConfirmBox ( _hider - > offeredText ( ) , lang ( lng_forward_send ) ) ;
2015-07-17 22:17:37 +03:00
connect ( _forwardConfirm , SIGNAL ( confirmed ( ) ) , _hider , SLOT ( forward ( ) ) ) ;
2014-12-12 19:27:03 +03:00
connect ( _forwardConfirm , SIGNAL ( cancelled ( ) ) , this , SLOT ( onForwardCancel ( ) ) ) ;
connect ( _forwardConfirm , SIGNAL ( destroyed ( QObject * ) ) , this , SLOT ( onForwardCancel ( QObject * ) ) ) ;
2015-12-07 21:09:05 +03:00
Ui : : showLayer ( _forwardConfirm ) ;
2014-12-12 19:27:03 +03:00
}
2014-05-30 12:53:19 +04:00
}
2014-12-12 19:27:03 +03:00
void MainWidget : : onForwardCancel ( QObject * obj ) {
if ( ! obj | | obj = = _forwardConfirm ) {
if ( _forwardConfirm ) {
2014-12-13 02:34:50 +03:00
if ( ! obj ) _forwardConfirm - > startHide ( ) ;
2014-12-12 19:27:03 +03:00
_forwardConfirm = 0 ;
}
2015-07-17 22:17:37 +03:00
if ( _hider ) _hider - > offerPeer ( 0 ) ;
2014-12-12 19:27:03 +03:00
}
2014-05-30 12:53:19 +04:00
}
void MainWidget : : dialogsActivate ( ) {
2016-04-13 00:31:28 +03:00
_dialogs - > activate ( ) ;
2014-05-30 12:53:19 +04:00
}
2015-06-24 20:24:48 +03:00
DragState MainWidget : : getDragState ( const QMimeData * mime ) {
2016-04-13 00:31:28 +03:00
return _history - > getDragState ( mime ) ;
2015-06-24 20:24:48 +03:00
}
2015-04-04 23:01:34 +03:00
bool MainWidget : : leaveChatFailed ( PeerData * peer , const RPCError & error ) {
2016-04-08 14:44:35 +04:00
if ( MTP : : isDefaultHandledError ( error ) ) return false ;
2015-04-04 23:01:34 +03:00
2015-11-19 14:28:17 +03:00
if ( error . type ( ) = = qstr ( " USER_NOT_PARTICIPANT " ) | | error . type ( ) = = qstr ( " CHAT_ID_INVALID " ) | | error . type ( ) = = qstr ( " PEER_ID_INVALID " ) ) { // left this chat already
2015-09-24 11:58:10 +03:00
deleteConversation ( peer ) ;
2014-05-30 12:53:19 +04:00
return true ;
}
return false ;
}
2015-08-04 18:01:47 +03:00
void MainWidget : : deleteHistoryAfterLeave ( PeerData * peer , const MTPUpdates & updates ) {
2015-04-02 13:33:19 +03:00
sentUpdatesReceived ( updates ) ;
2015-09-24 11:58:10 +03:00
deleteConversation ( peer ) ;
2014-05-30 12:53:19 +04:00
}
void MainWidget : : deleteHistoryPart ( PeerData * peer , const MTPmessages_AffectedHistory & result ) {
2016-04-08 14:44:35 +04:00
const auto & d ( result . c_messages_affectedHistory ( ) ) ;
2016-03-13 18:45:00 +03:00
if ( peer & & peer - > isChannel ( ) ) {
if ( peer - > asChannel ( ) - > ptsUpdated ( d . vpts . v , d . vpts_count . v ) ) {
peer - > asChannel ( ) - > ptsApplySkippedUpdates ( ) ;
2016-05-25 15:09:05 +03:00
Notify : : peerUpdatedSendDelayed ( ) ;
2016-03-13 18:45:00 +03:00
}
} else {
if ( ptsUpdated ( d . vpts . v , d . vpts_count . v ) ) {
ptsApplySkippedUpdates ( ) ;
2016-05-25 15:09:05 +03:00
Notify : : peerUpdatedSendDelayed ( ) ;
2016-03-13 18:45:00 +03:00
}
2015-09-20 12:54:22 +03:00
}
2014-05-30 12:53:19 +04:00
int32 offset = d . voffset . v ;
2015-09-08 20:22:29 +03:00
if ( ! MTP : : authedId ( ) ) return ;
if ( offset < = 0 ) {
cRefReportSpamStatuses ( ) . remove ( peer - > id ) ;
Local : : writeReportSpamStatuses ( ) ;
return ;
}
2014-05-30 12:53:19 +04:00
2016-02-15 14:11:07 +03:00
MTP : : send ( MTPmessages_DeleteHistory ( peer - > input , MTP_int ( 0 ) ) , rpcDone ( & MainWidget : : deleteHistoryPart , peer ) ) ;
2014-05-30 12:53:19 +04:00
}
2015-09-07 10:52:37 +03:00
void MainWidget : : deleteMessages ( PeerData * peer , const QVector < MTPint > & ids ) {
if ( peer - > isChannel ( ) ) {
2015-09-17 00:15:13 +03:00
MTP : : send ( MTPchannels_DeleteMessages ( peer - > asChannel ( ) - > inputChannel , MTP_vector < MTPint > ( ids ) ) , rpcDone ( & MainWidget : : messagesAffected , peer ) ) ;
2015-09-07 10:52:37 +03:00
} else {
MTP : : send ( MTPmessages_DeleteMessages ( MTP_vector < MTPint > ( ids ) ) , rpcDone ( & MainWidget : : messagesAffected , peer ) ) ;
}
2015-03-19 12:18:19 +03:00
}
2014-05-30 12:53:19 +04:00
void MainWidget : : deletedContact ( UserData * user , const MTPcontacts_Link & result ) {
2016-05-25 15:09:05 +03:00
auto & d ( result . c_contacts_link ( ) ) ;
App : : feedUsersDelayed ( MTP_vector < MTPUser > ( 1 , d . vuser ) ) ;
App : : feedUserLinkDelayed ( MTP_int ( peerToUser ( user - > id ) ) , d . vmy_link , d . vforeign_link ) ;
Notify : : peerUpdatedSendDelayed ( ) ;
2014-05-30 12:53:19 +04:00
}
2015-11-13 18:14:33 +03:00
void MainWidget : : removeDialog ( History * history ) {
2016-04-13 00:31:28 +03:00
_dialogs - > removeDialog ( history ) ;
2015-11-13 18:14:33 +03:00
}
2015-09-24 11:58:10 +03:00
void MainWidget : : deleteConversation ( PeerData * peer , bool deleteHistory ) {
if ( activePeer ( ) = = peer ) {
2015-12-13 14:36:08 +03:00
Ui : : showChatsList ( ) ;
2015-09-24 11:58:10 +03:00
}
2015-09-19 12:13:21 +03:00
if ( History * h = App : : historyLoaded ( peer - > id ) ) {
2015-11-13 18:14:33 +03:00
removeDialog ( h ) ;
2015-11-20 21:24:44 +03:00
if ( peer - > isMegagroup ( ) & & peer - > asChannel ( ) - > mgInfo - > migrateFromPtr ) {
if ( History * migrated = App : : historyLoaded ( peer - > asChannel ( ) - > mgInfo - > migrateFromPtr - > id ) ) {
if ( migrated - > lastMsg ) { // return initial dialog
migrated - > setLastMessage ( migrated - > lastMsg ) ;
} else {
checkPeerHistory ( migrated - > peer ) ;
}
}
}
2015-09-19 12:13:21 +03:00
h - > clear ( ) ;
2015-09-24 11:58:10 +03:00
h - > newLoaded = true ;
h - > oldLoaded = deleteHistory ;
if ( h - > isChannel ( ) ) {
h - > asChannelHistory ( ) - > clearOther ( ) ;
}
}
if ( peer - > isChannel ( ) ) {
peer - > asChannel ( ) - > ptsWaitingForShortPoll ( - 1 ) ;
}
if ( deleteHistory ) {
MTP : : send ( MTPmessages_DeleteHistory ( peer - > input , MTP_int ( 0 ) ) , rpcDone ( & MainWidget : : deleteHistoryPart , peer ) ) ;
2015-09-19 12:13:21 +03:00
}
2014-05-30 12:53:19 +04:00
}
2016-03-13 18:45:00 +03:00
void MainWidget : : deleteAllFromUser ( ChannelData * channel , UserData * from ) {
t_assert ( channel ! = nullptr & & from ! = nullptr ) ;
QVector < MsgId > toDestroy ;
2016-03-14 19:59:18 +03:00
if ( History * history = App : : historyLoaded ( channel - > id ) ) {
for ( HistoryBlock * block : history - > blocks ) {
for ( HistoryItem * item : block - > items ) {
if ( item - > from ( ) = = from & & item - > type ( ) = = HistoryItemMsg & & item - > canDelete ( ) ) {
toDestroy . push_back ( item - > id ) ;
2016-03-13 18:45:00 +03:00
}
}
}
2016-03-14 19:59:18 +03:00
for ( const MsgId & msgId : toDestroy ) {
if ( HistoryItem * item = App : : histItemById ( peerToChannel ( channel - > id ) , msgId ) ) {
2016-03-13 18:45:00 +03:00
item - > destroy ( ) ;
}
}
}
MTP : : send ( MTPchannels_DeleteUserHistory ( channel - > inputChannel , from - > inputUser ) , rpcDone ( & MainWidget : : deleteAllFromUserPart , { channel , from } ) ) ;
}
void MainWidget : : deleteAllFromUserPart ( DeleteAllFromUserParams params , const MTPmessages_AffectedHistory & result ) {
2016-04-08 14:44:35 +04:00
const auto & d ( result . c_messages_affectedHistory ( ) ) ;
2016-03-13 18:45:00 +03:00
if ( params . channel - > ptsUpdated ( d . vpts . v , d . vpts_count . v ) ) {
params . channel - > ptsApplySkippedUpdates ( ) ;
2016-05-25 15:09:05 +03:00
Notify : : peerUpdatedSendDelayed ( ) ;
2016-03-13 18:45:00 +03:00
}
int32 offset = d . voffset . v ;
if ( ! MTP : : authedId ( ) ) return ;
if ( offset > 0 ) {
MTP : : send ( MTPchannels_DeleteUserHistory ( params . channel - > inputChannel , params . from - > inputUser ) , rpcDone ( & MainWidget : : deleteAllFromUserPart , params ) ) ;
2016-03-14 19:59:18 +03:00
} else if ( History * h = App : : historyLoaded ( params . channel ) ) {
2016-03-13 18:45:00 +03:00
if ( ! h - > lastMsg ) {
checkPeerHistory ( params . channel ) ;
}
}
}
2014-05-30 12:53:19 +04:00
void MainWidget : : clearHistory ( PeerData * peer ) {
2015-09-19 12:13:21 +03:00
if ( History * h = App : : historyLoaded ( peer - > id ) ) {
if ( h - > lastMsg ) {
Local : : addSavedPeer ( h - > peer , h - > lastMsg - > date ) ;
}
h - > clear ( ) ;
h - > newLoaded = h - > oldLoaded = true ;
2014-05-30 12:53:19 +04:00
}
2015-12-13 14:36:08 +03:00
Ui : : showPeerHistory ( peer - > id , ShowAtUnreadMsgId ) ;
2014-05-30 12:53:19 +04:00
MTP : : send ( MTPmessages_DeleteHistory ( peer - > input , MTP_int ( 0 ) ) , rpcDone ( & MainWidget : : deleteHistoryPart , peer ) ) ;
}
2015-09-16 16:04:08 +03:00
void MainWidget : : addParticipants ( PeerData * chatOrChannel , const QVector < UserData * > & users ) {
2015-09-17 00:15:13 +03:00
if ( chatOrChannel - > isChat ( ) ) {
for ( QVector < UserData * > : : const_iterator i = users . cbegin ( ) , e = users . cend ( ) ; i ! = e ; + + i ) {
2015-09-16 16:04:08 +03:00
MTP : : send ( MTPmessages_AddChatUser ( chatOrChannel - > asChat ( ) - > inputChat , ( * i ) - > inputUser , MTP_int ( ForwardOnAdd ) ) , rpcDone ( & MainWidget : : sentUpdatesReceived ) , rpcFail ( & MainWidget : : addParticipantFail , * i ) , 0 , 5 ) ;
}
2015-09-17 00:15:13 +03:00
} else if ( chatOrChannel - > isChannel ( ) ) {
QVector < MTPInputUser > inputUsers ;
2015-12-06 18:50:02 +03:00
inputUsers . reserve ( qMin ( users . size ( ) , int ( MaxUsersPerInvite ) ) ) ;
2015-09-17 00:15:13 +03:00
for ( QVector < UserData * > : : const_iterator i = users . cbegin ( ) , e = users . cend ( ) ; i ! = e ; + + i ) {
inputUsers . push_back ( ( * i ) - > inputUser ) ;
2015-12-06 18:50:02 +03:00
if ( inputUsers . size ( ) = = MaxUsersPerInvite ) {
MTP : : send ( MTPchannels_InviteToChannel ( chatOrChannel - > asChannel ( ) - > inputChannel , MTP_vector < MTPInputUser > ( inputUsers ) ) , rpcDone ( & MainWidget : : inviteToChannelDone , chatOrChannel - > asChannel ( ) ) , rpcFail ( & MainWidget : : addParticipantsFail , chatOrChannel - > asChannel ( ) ) , 0 , 5 ) ;
inputUsers . clear ( ) ;
}
}
if ( ! inputUsers . isEmpty ( ) ) {
MTP : : send ( MTPchannels_InviteToChannel ( chatOrChannel - > asChannel ( ) - > inputChannel , MTP_vector < MTPInputUser > ( inputUsers ) ) , rpcDone ( & MainWidget : : inviteToChannelDone , chatOrChannel - > asChannel ( ) ) , rpcFail ( & MainWidget : : addParticipantsFail , chatOrChannel - > asChannel ( ) ) , 0 , 5 ) ;
2015-09-17 00:15:13 +03:00
}
2014-05-30 12:53:19 +04:00
}
}
2015-06-15 20:19:24 +03:00
bool MainWidget : : addParticipantFail ( UserData * user , const RPCError & error ) {
2016-04-08 14:44:35 +04:00
if ( MTP : : isDefaultHandledError ( error ) ) return false ;
2015-04-04 23:01:34 +03:00
2015-06-15 20:19:24 +03:00
QString text = lang ( lng_failed_add_participant ) ;
2016-04-08 14:44:35 +04:00
if ( error . type ( ) = = qstr ( " USER_LEFT_CHAT " ) ) { // trying to return a user who has left
} else if ( error . type ( ) = = qstr ( " USER_KICKED " ) ) { // trying to return a user who was kicked by admin
2016-03-23 19:50:40 +03:00
text = lang ( lng_cant_invite_banned ) ;
2016-04-08 14:44:35 +04:00
} else if ( error . type ( ) = = qstr ( " USER_PRIVACY_RESTRICTED " ) ) {
2016-02-14 21:29:17 +03:00
text = lang ( lng_cant_invite_privacy ) ;
2016-04-08 14:44:35 +04:00
} else if ( error . type ( ) = = qstr ( " USER_NOT_MUTUAL_CONTACT " ) ) { // trying to return user who does not have me in contacts
2015-08-07 15:11:50 +03:00
text = lang ( lng_failed_add_not_mutual ) ;
2016-04-08 14:44:35 +04:00
} else if ( error . type ( ) = = qstr ( " USER_ALREADY_PARTICIPANT " ) & & user - > botInfo ) {
2015-06-15 20:19:24 +03:00
text = lang ( lng_bot_already_in_group ) ;
2016-04-08 14:44:35 +04:00
} else if ( error . type ( ) = = qstr ( " PEER_FLOOD " ) ) {
2016-04-06 17:19:25 +04:00
text = cantInviteError ( ) ;
2014-05-30 12:53:19 +04:00
}
2015-12-07 21:09:05 +03:00
Ui : : showLayer ( new InformBox ( text ) ) ;
2014-05-30 12:53:19 +04:00
return false ;
}
2015-11-02 17:33:57 -05:00
bool MainWidget : : addParticipantsFail ( ChannelData * channel , const RPCError & error ) {
2016-04-08 14:44:35 +04:00
if ( MTP : : isDefaultHandledError ( error ) ) return false ;
2015-09-17 00:15:13 +03:00
QString text = lang ( lng_failed_add_participant ) ;
2016-04-08 14:44:35 +04:00
if ( error . type ( ) = = qstr ( " USER_LEFT_CHAT " ) ) { // trying to return banned user to his group
} else if ( error . type ( ) = = qstr ( " USER_KICKED " ) ) { // trying to return a user who was kicked by admin
2016-03-23 19:50:40 +03:00
text = lang ( lng_cant_invite_banned ) ;
2016-04-08 14:44:35 +04:00
} else if ( error . type ( ) = = qstr ( " USER_PRIVACY_RESTRICTED " ) ) {
2016-03-23 19:50:40 +03:00
text = lang ( channel - > isMegagroup ( ) ? lng_cant_invite_privacy : lng_cant_invite_privacy_channel ) ;
2016-04-08 14:44:35 +04:00
} else if ( error . type ( ) = = qstr ( " USER_NOT_MUTUAL_CONTACT " ) ) { // trying to return user who does not have me in contacts
2015-11-02 17:33:57 -05:00
text = lang ( channel - > isMegagroup ( ) ? lng_failed_add_not_mutual : lng_failed_add_not_mutual_channel ) ;
2016-04-08 14:44:35 +04:00
} else if ( error . type ( ) = = qstr ( " PEER_FLOOD " ) ) {
2016-04-06 17:19:25 +04:00
text = cantInviteError ( ) ;
2015-09-17 00:15:13 +03:00
}
2015-12-07 21:09:05 +03:00
Ui : : showLayer ( new InformBox ( text ) ) ;
2015-09-17 00:15:13 +03:00
return false ;
}
2014-05-30 12:53:19 +04:00
void MainWidget : : kickParticipant ( ChatData * chat , UserData * user ) {
2015-09-03 13:48:40 +03:00
MTP : : send ( MTPmessages_DeleteChatUser ( chat - > inputChat , user - > inputUser ) , rpcDone ( & MainWidget : : sentUpdatesReceived ) , rpcFail ( & MainWidget : : kickParticipantFail , chat ) ) ;
2015-12-07 21:09:05 +03:00
Ui : : hideLayer ( ) ;
2015-12-13 14:36:08 +03:00
Ui : : showPeerHistory ( chat - > id , ShowAtTheEndMsgId ) ;
2014-05-30 12:53:19 +04:00
}
2015-04-04 23:01:34 +03:00
bool MainWidget : : kickParticipantFail ( ChatData * chat , const RPCError & error ) {
2016-04-08 14:44:35 +04:00
if ( MTP : : isDefaultHandledError ( error ) ) return false ;
2015-04-04 23:01:34 +03:00
error . type ( ) ;
2014-05-30 12:53:19 +04:00
return false ;
}
void MainWidget : : checkPeerHistory ( PeerData * peer ) {
2015-11-02 17:33:57 -05:00
if ( peer - > isChannel ( ) & & ! peer - > isMegagroup ( ) ) {
2016-02-12 19:35:06 +03:00
MTP : : send ( MTPchannels_GetImportantHistory ( peer - > asChannel ( ) - > inputChannel , MTP_int ( 0 ) , MTP_int ( 0 ) , MTP_int ( 0 ) , MTP_int ( 1 ) , MTP_int ( 0 ) , MTP_int ( 0 ) ) , rpcDone ( & MainWidget : : checkedHistory , peer ) ) ;
2015-09-04 16:01:31 +03:00
} else {
2016-02-12 19:35:06 +03:00
MTP : : send ( MTPmessages_GetHistory ( peer - > input , MTP_int ( 0 ) , MTP_int ( 0 ) , MTP_int ( 0 ) , MTP_int ( 1 ) , MTP_int ( 0 ) , MTP_int ( 0 ) ) , rpcDone ( & MainWidget : : checkedHistory , peer ) ) ;
2015-09-04 16:01:31 +03:00
}
2014-05-30 12:53:19 +04:00
}
void MainWidget : : checkedHistory ( PeerData * peer , const MTPmessages_Messages & result ) {
const QVector < MTPMessage > * v = 0 ;
2015-09-21 23:57:42 +03:00
const QVector < MTPMessageGroup > * collapsed = 0 ;
2015-09-04 16:01:31 +03:00
switch ( result . type ( ) ) {
case mtpc_messages_messages : {
2016-04-08 14:44:35 +04:00
const auto & d ( result . c_messages_messages ( ) ) ;
2014-05-30 12:53:19 +04:00
App : : feedUsers ( d . vusers ) ;
2015-06-30 01:09:23 +03:00
App : : feedChats ( d . vchats ) ;
2014-05-30 12:53:19 +04:00
v = & d . vmessages . c_vector ( ) . v ;
2015-09-04 16:01:31 +03:00
} break ;
case mtpc_messages_messagesSlice : {
2016-04-08 14:44:35 +04:00
const auto & d ( result . c_messages_messagesSlice ( ) ) ;
2014-05-30 12:53:19 +04:00
App : : feedUsers ( d . vusers ) ;
2015-06-30 01:09:23 +03:00
App : : feedChats ( d . vchats ) ;
2014-05-30 12:53:19 +04:00
v = & d . vmessages . c_vector ( ) . v ;
2015-09-04 16:01:31 +03:00
} break ;
2015-09-13 11:41:27 +03:00
case mtpc_messages_channelMessages : {
2016-04-08 14:44:35 +04:00
const auto & d ( result . c_messages_channelMessages ( ) ) ;
2015-09-13 11:41:27 +03:00
if ( peer & & peer - > isChannel ( ) ) {
peer - > asChannel ( ) - > ptsReceived ( d . vpts . v ) ;
} else {
2015-09-19 12:13:21 +03:00
LOG ( ( " API Error: received messages.channelMessages when no channel was passed! (MainWidget::checkedHistory) " ) ) ;
2015-09-13 11:41:27 +03:00
}
2015-09-21 23:57:42 +03:00
collapsed = & d . vcollapsed . c_vector ( ) . v ;
2015-09-04 16:01:31 +03:00
App : : feedUsers ( d . vusers ) ;
App : : feedChats ( d . vchats ) ;
v = & d . vmessages . c_vector ( ) . v ;
} break ;
2014-05-30 12:53:19 +04:00
}
if ( ! v ) return ;
if ( v - > isEmpty ( ) ) {
2015-10-29 15:10:49 -04:00
if ( peer - > isChat ( ) & & peer - > asChat ( ) - > haveLeft ( ) ) {
2015-09-24 11:58:10 +03:00
deleteConversation ( peer , false ) ;
2015-09-21 23:57:42 +03:00
} else if ( peer - > isChannel ( ) ) {
2015-09-23 20:43:08 +03:00
if ( peer - > asChannel ( ) - > inviter > 0 & & peer - > asChannel ( ) - > amIn ( ) ) {
if ( UserData * from = App : : userLoaded ( peer - > asChannel ( ) - > inviter ) ) {
History * h = App : : history ( peer - > id ) ;
h - > clear ( true ) ;
h - > addNewerSlice ( QVector < MTPMessage > ( ) , 0 ) ;
h - > asChannelHistory ( ) - > insertJoinedMessage ( true ) ;
2016-04-13 00:31:28 +03:00
_history - > peerMessagesUpdated ( h - > peer - > id ) ;
2015-09-21 23:57:42 +03:00
}
}
} else {
2015-08-07 15:11:50 +03:00
History * h = App : : historyLoaded ( peer - > id ) ;
if ( h ) Local : : addSavedPeer ( peer , h - > lastMsgDate ) ;
}
2014-05-30 12:53:19 +04:00
} else {
2015-09-21 23:57:42 +03:00
History * h = App : : history ( peer - > id ) ;
2015-06-15 20:19:24 +03:00
if ( ! h - > lastMsg ) {
2015-09-21 23:57:42 +03:00
HistoryItem * item = h - > addNewMessage ( ( * v ) [ 0 ] , NewMessageLast ) ;
2016-02-14 18:58:39 +03:00
if ( item & & collapsed & & ! collapsed - > isEmpty ( ) & & collapsed - > at ( 0 ) . type ( ) = = mtpc_messageGroup & & h - > isChannel ( ) ) {
2015-09-21 23:57:42 +03:00
if ( collapsed - > at ( 0 ) . c_messageGroup ( ) . vmax_id . v > item - > id ) {
if ( h - > asChannelHistory ( ) - > onlyImportant ( ) ) {
h - > asChannelHistory ( ) - > clearOther ( ) ;
} else {
h - > setNotLoadedAtBottom ( ) ;
}
}
}
}
if ( ! h - > lastMsgDate . isNull ( ) & & h - > loadedAtBottom ( ) ) {
2015-09-23 20:43:08 +03:00
if ( peer - > isChannel ( ) & & peer - > asChannel ( ) - > inviter > 0 & & h - > lastMsgDate < = peer - > asChannel ( ) - > inviteDate & & peer - > asChannel ( ) - > amIn ( ) ) {
if ( UserData * from = App : : userLoaded ( peer - > asChannel ( ) - > inviter ) ) {
h - > asChannelHistory ( ) - > insertJoinedMessage ( true ) ;
2016-04-13 00:31:28 +03:00
_history - > peerMessagesUpdated ( h - > peer - > id ) ;
2015-09-21 23:57:42 +03:00
}
}
2014-05-30 12:53:19 +04:00
}
}
}
2015-09-09 10:46:31 +03:00
bool MainWidget : : sendMessageFail ( const RPCError & error ) {
2016-04-08 14:44:35 +04:00
if ( MTP : : isDefaultHandledError ( error ) ) return false ;
2015-09-09 10:46:31 +03:00
2016-04-08 14:44:35 +04:00
if ( error . type ( ) = = qstr ( " PEER_FLOOD " ) ) {
2016-04-06 17:19:25 +04:00
Ui : : showLayer ( new InformBox ( cantInviteError ( ) ) ) ;
2015-09-09 10:46:31 +03:00
return true ;
}
2015-01-05 23:17:33 +03:00
return false ;
}
2015-02-03 18:02:46 +03:00
void MainWidget : : onCacheBackground ( ) {
const QPixmap & bg ( * cChatBackground ( ) ) ;
2015-02-03 19:44:54 +03:00
if ( cTileBackground ( ) ) {
QImage result ( _willCacheFor . width ( ) * cIntRetinaFactor ( ) , _willCacheFor . height ( ) * cIntRetinaFactor ( ) , QImage : : Format_RGB32 ) ;
2015-02-04 10:59:20 +03:00
result . setDevicePixelRatio ( cRetinaFactor ( ) ) ;
2015-02-03 19:44:54 +03:00
{
QPainter p ( & result ) ;
int left = 0 , top = 0 , right = _willCacheFor . width ( ) , bottom = _willCacheFor . height ( ) ;
float64 w = bg . width ( ) / cRetinaFactor ( ) , h = bg . height ( ) / cRetinaFactor ( ) ;
int sx = 0 , sy = 0 , cx = qCeil ( _willCacheFor . width ( ) / w ) , cy = qCeil ( _willCacheFor . height ( ) / h ) ;
for ( int i = sx ; i < cx ; + + i ) {
for ( int j = sy ; j < cy ; + + j ) {
p . drawPixmap ( QPointF ( i * w , j * h ) , bg ) ;
}
}
}
_cachedX = 0 ;
_cachedY = 0 ;
_cachedBackground = QPixmap : : fromImage ( result ) ;
} else {
QRect to , from ;
backgroundParams ( _willCacheFor , to , from ) ;
_cachedX = to . x ( ) ;
_cachedY = to . y ( ) ;
_cachedBackground = QPixmap : : fromImage ( bg . toImage ( ) . copy ( from ) . scaled ( to . width ( ) * cIntRetinaFactor ( ) , to . height ( ) * cIntRetinaFactor ( ) , Qt : : IgnoreAspectRatio , Qt : : SmoothTransformation ) ) ;
_cachedBackground . setDevicePixelRatio ( cRetinaFactor ( ) ) ;
}
2015-02-03 18:02:46 +03:00
_cachedFor = _willCacheFor ;
}
2014-05-30 12:53:19 +04:00
void MainWidget : : forwardSelectedItems ( ) {
2016-04-13 00:31:28 +03:00
if ( _overview ) {
_overview - > onForwardSelected ( ) ;
2014-08-20 09:32:50 +04:00
} else {
2016-04-13 00:31:28 +03:00
_history - > onForwardSelected ( ) ;
2014-08-20 09:32:50 +04:00
}
2014-05-30 12:53:19 +04:00
}
void MainWidget : : deleteSelectedItems ( ) {
2016-04-13 00:31:28 +03:00
if ( _overview ) {
_overview - > onDeleteSelected ( ) ;
2014-08-20 09:32:50 +04:00
} else {
2016-04-13 00:31:28 +03:00
_history - > onDeleteSelected ( ) ;
2014-08-20 09:32:50 +04:00
}
2014-05-30 12:53:19 +04:00
}
void MainWidget : : clearSelectedItems ( ) {
2016-04-13 00:31:28 +03:00
if ( _overview ) {
_overview - > onClearSelected ( ) ;
2014-08-20 09:32:50 +04:00
} else {
2016-04-13 00:31:28 +03:00
_history - > onClearSelected ( ) ;
2014-08-20 09:32:50 +04:00
}
2014-05-30 12:53:19 +04:00
}
2016-04-09 22:45:55 +04:00
Dialogs : : IndexedList * MainWidget : : contactsList ( ) {
2016-04-13 00:31:28 +03:00
return _dialogs - > contactsList ( ) ;
2014-05-30 12:53:19 +04:00
}
2016-04-09 22:45:55 +04:00
Dialogs : : IndexedList * MainWidget : : dialogsList ( ) {
2016-04-13 00:31:28 +03:00
return _dialogs - > dialogsList ( ) ;
2015-06-15 20:19:24 +03:00
}
2016-04-05 11:45:53 +04:00
namespace {
QString parseCommandFromMessage ( History * history , const QString & message ) {
if ( history - > peer - > id ! = peerFromUser ( ServiceUserId ) ) {
return QString ( ) ;
}
if ( message . size ( ) < 3 | | message . at ( 0 ) ! = ' * ' | | message . at ( message . size ( ) - 1 ) ! = ' * ' ) {
return QString ( ) ;
}
QString command = message . mid ( 1 , message . size ( ) - 2 ) ;
QStringList commands ;
commands . push_back ( qsl ( " new_version_text " ) ) ;
commands . push_back ( qsl ( " all_new_version_texts " ) ) ;
if ( commands . indexOf ( command ) < 0 ) {
return QString ( ) ;
}
return command ;
}
void executeParsedCommand ( const QString & command ) {
if ( command . isEmpty ( ) | | ! App : : wnd ( ) ) {
return ;
}
if ( command = = qsl ( " new_version_text " ) ) {
App : : wnd ( ) - > serviceNotification ( langNewVersionText ( ) ) ;
} else if ( command = = qsl ( " all_new_version_texts " ) ) {
for ( int i = 0 ; i < languageCount ; + + i ) {
2016-05-14 21:14:55 +03:00
App : : wnd ( ) - > serviceNotification ( langNewVersionTextForLang ( i ) ) ;
2016-04-05 11:45:53 +04:00
}
}
}
} // namespace
2016-04-30 20:04:14 +03:00
void MainWidget : : sendMessage ( const MessageToSend & message ) {
auto history = message . history ;
2016-05-05 19:04:17 +03:00
const auto & textWithTags = message . textWithTags ;
2015-08-30 17:57:21 +03:00
2016-04-30 20:04:14 +03:00
readServerHistory ( history , false ) ;
_history - > fastShowAtEnd ( history ) ;
2015-08-30 17:57:21 +03:00
2016-04-30 20:04:14 +03:00
if ( ! history | | ! _history - > canSendMessages ( history - > peer ) ) {
2015-10-23 18:06:56 +02:00
return ;
2015-08-30 17:57:21 +03:00
}
2015-08-24 13:53:04 +03:00
2016-05-05 19:04:17 +03:00
saveRecentHashtags ( textWithTags . text ) ;
2015-10-23 18:06:56 +02:00
2016-05-05 19:04:17 +03:00
EntitiesInText sendingEntities , leftEntities = entitiesFromTextTags ( textWithTags . tags ) ;
2016-04-30 20:04:14 +03:00
auto prepareFlags = itemTextOptions ( history , App : : self ( ) ) . flags ;
2016-05-05 19:04:17 +03:00
QString sendingText , leftText = prepareTextWithEntities ( textWithTags . text , prepareFlags , & leftEntities ) ;
2015-10-23 18:06:56 +02:00
2016-05-05 19:04:17 +03:00
QString command = parseCommandFromMessage ( history , textWithTags . text ) ;
2016-04-23 14:40:42 +03:00
HistoryItem * lastMessage = nullptr ;
2016-04-05 11:45:53 +04:00
2016-04-30 20:04:14 +03:00
MsgId replyTo = ( message . replyTo < 0 ) ? _history - > replyToId ( ) : 0 ;
2016-04-05 11:45:53 +04:00
while ( command . isEmpty ( ) & & textSplit ( sendingText , sendingEntities , leftText , leftEntities , MaxMessageSize ) ) {
2016-04-30 20:04:14 +03:00
FullMsgId newId ( peerToChannel ( history - > peer - > id ) , clientMsgId ( ) ) ;
2016-03-24 13:12:18 +03:00
uint64 randomId = rand_value < uint64 > ( ) ;
2014-11-05 20:43:32 +03:00
2016-04-30 20:04:14 +03:00
trimTextWithEntities ( sendingText , & sendingEntities ) ;
2015-08-24 13:53:04 +03:00
2014-06-15 16:31:03 +04:00
App : : historyRegRandom ( randomId , newId ) ;
2016-04-30 20:04:14 +03:00
App : : historyRegSentData ( randomId , history - > peer - > id , sendingText ) ;
2014-07-04 15:12:54 +04:00
2014-11-05 20:43:32 +03:00
MTPstring msgText ( MTP_string ( sendingText ) ) ;
2016-04-30 20:04:14 +03:00
MTPDmessage : : Flags flags = newMessageFlags ( history - > peer ) | MTPDmessage : : Flag : : f_entities ; // unread, out
2016-03-19 19:55:15 +03:00
MTPmessages_SendMessage : : Flags sendFlags = 0 ;
2015-04-07 01:15:29 +03:00
if ( replyTo ) {
2016-03-19 19:55:15 +03:00
flags | = MTPDmessage : : Flag : : f_reply_to_msg_id ;
sendFlags | = MTPmessages_SendMessage : : Flag : : f_reply_to_msg_id ;
2015-04-07 01:15:29 +03:00
}
2015-04-08 02:03:32 +03:00
MTPMessageMedia media = MTP_messageMediaEmpty ( ) ;
2016-04-30 20:04:14 +03:00
if ( message . webPageId = = CancelledWebPageId ) {
2016-03-19 19:55:15 +03:00
sendFlags | = MTPmessages_SendMessage : : Flag : : f_no_webpage ;
2016-04-30 20:04:14 +03:00
} else if ( message . webPageId ) {
WebPageData * page = App : : webPage ( message . webPageId ) ;
2015-04-08 02:03:32 +03:00
media = MTP_messageMediaWebPage ( MTP_webPagePending ( MTP_long ( page - > id ) , MTP_int ( page - > pendingTill ) ) ) ;
2016-03-19 19:55:15 +03:00
flags | = MTPDmessage : : Flag : : f_media ;
2015-04-08 02:03:32 +03:00
}
2016-04-30 20:04:14 +03:00
bool channelPost = history - > peer - > isChannel ( ) & & ! history - > peer - > isMegagroup ( ) & & history - > peer - > asChannel ( ) - > canPublish ( ) & & ( history - > peer - > asChannel ( ) - > isBroadcast ( ) | | message . broadcast ) ;
bool showFromName = ! channelPost | | history - > peer - > asChannel ( ) - > addsSignature ( ) ;
bool silentPost = channelPost & & message . silent ;
2016-02-17 19:37:21 +03:00
if ( channelPost ) {
2016-03-19 19:55:15 +03:00
sendFlags | = MTPmessages_SendMessage : : Flag : : f_broadcast ;
flags | = MTPDmessage : : Flag : : f_views ;
flags | = MTPDmessage : : Flag : : f_post ;
2016-02-17 19:37:21 +03:00
}
if ( showFromName ) {
2016-03-19 19:55:15 +03:00
flags | = MTPDmessage : : Flag : : f_from_id ;
2015-09-06 13:17:09 +03:00
}
2016-02-25 19:19:54 +03:00
if ( silentPost ) {
2016-03-19 19:55:15 +03:00
sendFlags | = MTPmessages_SendMessage : : Flag : : f_silent ;
2016-02-25 19:19:54 +03:00
}
2015-10-23 18:06:56 +02:00
MTPVector < MTPMessageEntity > localEntities = linksToMTP ( sendingEntities ) , sentEntities = linksToMTP ( sendingEntities , true ) ;
if ( ! sentEntities . c_vector ( ) . v . isEmpty ( ) ) {
2016-03-19 19:55:15 +03:00
sendFlags | = MTPmessages_SendMessage : : Flag : : f_entities ;
2015-10-23 18:06:56 +02:00
}
2016-04-30 20:04:14 +03:00
lastMessage = history - > addNewMessage ( MTP_message ( MTP_flags ( flags ) , MTP_int ( newId . msg ) , MTP_int ( showFromName ? MTP : : authedId ( ) : 0 ) , peerToMTP ( history - > peer - > id ) , MTPnullFwdHeader , MTPint ( ) , MTP_int ( replyTo ) , MTP_int ( unixtime ( ) ) , msgText , media , MTPnullMarkup , localEntities , MTP_int ( 1 ) , MTPint ( ) ) , NewMessageUnread ) ;
history - > sendRequestId = MTP : : send ( MTPmessages_SendMessage ( MTP_flags ( sendFlags ) , history - > peer - > input , MTP_int ( replyTo ) , msgText , MTP_long ( randomId ) , MTPnullMarkup , sentEntities ) , rpcDone ( & MainWidget : : sentUpdatesReceived , randomId ) , rpcFail ( & MainWidget : : sendMessageFail ) , 0 , 0 , history - > sendRequestId ) ;
2014-11-05 20:43:32 +03:00
}
2016-04-30 20:04:14 +03:00
history - > lastSentMsg = lastMessage ;
2016-04-23 14:40:42 +03:00
2016-04-30 20:04:14 +03:00
finishForwarding ( history , message . broadcast , message . silent ) ;
2016-04-05 11:45:53 +04:00
executeParsedCommand ( command ) ;
2014-11-05 20:43:32 +03:00
}
2015-03-24 13:00:27 +03:00
void MainWidget : : saveRecentHashtags ( const QString & text ) {
bool found = false ;
QRegularExpressionMatch m ;
RecentHashtagPack recent ( cRecentWriteHashtags ( ) ) ;
for ( int32 i = 0 , next = 0 ; ( m = reHashtag ( ) . match ( text , i ) ) . hasMatch ( ) ; i = next ) {
i = m . capturedStart ( ) ;
next = m . capturedEnd ( ) ;
if ( m . hasMatch ( ) ) {
if ( ! m . capturedRef ( 1 ) . isEmpty ( ) ) {
+ + i ;
}
if ( ! m . capturedRef ( 2 ) . isEmpty ( ) ) {
- - next ;
}
}
if ( ! found & & cRecentWriteHashtags ( ) . isEmpty ( ) & & cRecentSearchHashtags ( ) . isEmpty ( ) ) {
2016-01-01 22:48:32 +08:00
Local : : readRecentHashtagsAndBots ( ) ;
2015-03-24 13:00:27 +03:00
recent = cRecentWriteHashtags ( ) ;
}
found = true ;
incrementRecentHashtag ( recent , text . mid ( i + 1 , next - i - 1 ) ) ;
}
if ( found ) {
cSetRecentWriteHashtags ( recent ) ;
2016-01-01 22:48:32 +08:00
Local : : writeRecentHashtagsAndBots ( ) ;
2015-03-24 13:00:27 +03:00
}
}
2014-06-15 16:31:03 +04:00
void MainWidget : : readServerHistory ( History * hist , bool force ) {
2016-04-11 14:59:01 +04:00
if ( ! hist | | ( ! force & & ! hist - > unreadCount ( ) ) ) return ;
2015-12-31 23:27:21 +08:00
2015-09-06 13:17:09 +03:00
MsgId upTo = hist - > inboxRead ( 0 ) ;
2015-09-23 20:43:08 +03:00
if ( hist - > isChannel ( ) & & ! hist - > peer - > asChannel ( ) - > amIn ( ) ) {
2016-05-12 19:05:20 +03:00
return ; // no read request for channels that I didn't join
2015-09-23 20:43:08 +03:00
}
ReadRequests : : const_iterator i = _readRequests . constFind ( hist - > peer ) ;
2016-05-12 19:05:20 +03:00
if ( i = = _readRequests . cend ( ) ) {
2015-09-06 13:17:09 +03:00
sendReadRequest ( hist - > peer , upTo ) ;
} else {
ReadRequestsPending : : iterator i = _readRequestsPending . find ( hist - > peer ) ;
if ( i = = _readRequestsPending . cend ( ) ) {
_readRequestsPending . insert ( hist - > peer , upTo ) ;
} else if ( i . value ( ) < upTo ) {
i . value ( ) = upTo ;
}
}
2014-06-15 16:31:03 +04:00
}
2015-12-11 21:11:38 +03:00
uint64 MainWidget : : animActiveTimeStart ( const HistoryItem * msg ) const {
2016-04-13 00:31:28 +03:00
return _history - > animActiveTimeStart ( msg ) ;
2014-07-04 15:12:54 +04:00
}
void MainWidget : : stopAnimActive ( ) {
2016-04-13 00:31:28 +03:00
_history - > stopAnimActive ( ) ;
2014-07-04 15:12:54 +04:00
}
2016-04-14 22:24:42 +03:00
void MainWidget : : sendBotCommand ( PeerData * peer , UserData * bot , const QString & cmd , MsgId replyTo ) {
_history - > sendBotCommand ( peer , bot , cmd , replyTo ) ;
2016-03-29 20:17:00 +03:00
}
2016-04-06 21:02:22 +04:00
void MainWidget : : app_sendBotCallback ( const HistoryMessageReplyMarkup : : Button * button , const HistoryItem * msg , int row , int col ) {
2016-04-13 00:31:28 +03:00
_history - > app_sendBotCallback ( button , msg , row , col ) ;
2015-06-10 18:54:24 +03:00
}
2016-01-01 02:34:56 +08:00
bool MainWidget : : insertBotCommand ( const QString & cmd , bool specialGif ) {
2016-04-13 00:31:28 +03:00
return _history - > insertBotCommand ( cmd , specialGif ) ;
2015-06-17 22:43:03 +03:00
}
2015-09-21 23:57:42 +03:00
void MainWidget : : searchMessages ( const QString & query , PeerData * inPeer ) {
2015-05-20 22:28:24 +03:00
App : : wnd ( ) - > hideMediaview ( ) ;
2016-04-13 00:31:28 +03:00
_dialogs - > searchMessages ( query , inPeer ) ;
2016-02-08 17:54:55 +03:00
if ( Adaptive : : OneColumn ( ) ) {
2015-12-13 14:36:08 +03:00
Ui : : showChatsList ( ) ;
2015-09-21 23:57:42 +03:00
} else {
2016-04-13 00:31:28 +03:00
_dialogs - > activate ( ) ;
2015-09-21 23:57:42 +03:00
}
2014-07-16 10:58:36 +04:00
}
2015-11-16 19:04:37 +03:00
bool MainWidget : : preloadOverview ( PeerData * peer , MediaOverviewType type ) {
MTPMessagesFilter filter = typeToMediaFilter ( type ) ;
if ( type = = OverviewCount ) return false ;
History * h = App : : history ( peer - > id ) ;
2015-11-18 16:11:56 +03:00
if ( h - > overviewCountLoaded ( type ) | | _overviewPreload [ type ] . constFind ( peer ) ! = _overviewPreload [ type ] . cend ( ) ) {
2015-11-16 19:04:37 +03:00
return false ;
}
2016-03-19 19:55:15 +03:00
MTPmessages_Search : : Flags flags = 0 ;
if ( peer - > isChannel ( ) & & ! peer - > isMegagroup ( ) ) {
flags | = MTPmessages_Search : : Flag : : f_important_only ;
}
_overviewPreload [ type ] . insert ( peer , MTP : : send ( MTPmessages_Search ( MTP_flags ( flags ) , peer - > input , MTP_string ( " " ) , filter , MTP_int ( 0 ) , MTP_int ( 0 ) , MTP_int ( 0 ) , MTP_int ( 0 ) , MTP_int ( 0 ) ) , rpcDone ( & MainWidget : : overviewPreloaded , peer ) , rpcFail ( & MainWidget : : overviewFailed , peer ) , 0 , 10 ) ) ;
2015-11-16 19:04:37 +03:00
return true ;
}
2014-08-15 15:19:32 +04:00
void MainWidget : : preloadOverviews ( PeerData * peer ) {
History * h = App : : history ( peer - > id ) ;
2015-11-16 19:04:37 +03:00
bool sending = false ;
2014-08-15 15:19:32 +04:00
for ( int32 i = 0 ; i < OverviewCount ; + + i ) {
2015-11-16 19:04:37 +03:00
if ( preloadOverview ( peer , MediaOverviewType ( i ) ) ) {
sending = true ;
2014-08-15 15:19:32 +04:00
}
}
2015-11-16 19:04:37 +03:00
if ( sending ) {
MTP : : sendAnything ( ) ;
2014-08-15 15:19:32 +04:00
}
}
void MainWidget : : overviewPreloaded ( PeerData * peer , const MTPmessages_Messages & result , mtpRequestId req ) {
MediaOverviewType type = OverviewCount ;
for ( int32 i = 0 ; i < OverviewCount ; + + i ) {
OverviewsPreload : : iterator j = _overviewPreload [ i ] . find ( peer ) ;
if ( j ! = _overviewPreload [ i ] . end ( ) & & j . value ( ) = = req ) {
type = MediaOverviewType ( i ) ;
_overviewPreload [ i ] . erase ( j ) ;
break ;
}
}
if ( type = = OverviewCount ) return ;
2015-11-18 16:11:56 +03:00
App : : history ( peer - > id ) - > overviewSliceDone ( type , result , true ) ;
2014-08-15 15:19:32 +04:00
2015-07-03 11:47:16 +03:00
mediaOverviewUpdated ( peer , type ) ;
2014-08-15 15:19:32 +04:00
}
2015-07-03 11:47:16 +03:00
void MainWidget : : mediaOverviewUpdated ( PeerData * peer , MediaOverviewType type ) {
2016-05-12 19:05:20 +03:00
// if (_profile) _profile->mediaOverviewUpdated(peer, type); TODO
2016-04-13 00:31:28 +03:00
if ( ! _player - > isHidden ( ) ) _player - > mediaOverviewUpdated ( peer , type ) ;
if ( _overview & & ( _overview - > peer ( ) = = peer | | _overview - > peer ( ) - > migrateFrom ( ) = = peer ) ) {
_overview - > mediaOverviewUpdated ( peer , type ) ;
2014-08-21 16:18:56 +04:00
int32 mask = 0 ;
2015-11-16 19:04:37 +03:00
History * h = peer ? App : : historyLoaded ( ( peer - > migrateTo ( ) ? peer - > migrateTo ( ) : peer ) - > id ) : 0 ;
History * m = ( peer & & peer - > migrateFrom ( ) ) ? App : : historyLoaded ( peer - > migrateFrom ( ) - > id ) : 0 ;
2014-08-21 16:18:56 +04:00
if ( h ) {
for ( int32 i = 0 ; i < OverviewCount ; + + i ) {
2016-04-13 00:31:28 +03:00
if ( ! h - > overview [ i ] . isEmpty ( ) | | h - > overviewCount ( i ) > 0 | | i = = _overview - > type ( ) ) {
2014-08-21 16:18:56 +04:00
mask | = ( 1 < < i ) ;
2015-11-18 16:11:56 +03:00
} else if ( m & & ( ! m - > overview [ i ] . isEmpty ( ) | | m - > overviewCount ( i ) > 0 ) ) {
2015-11-16 19:04:37 +03:00
mask | = ( 1 < < i ) ;
2014-08-21 16:18:56 +04:00
}
}
}
if ( mask ! = _mediaTypeMask ) {
2016-04-13 00:31:28 +03:00
_mediaType - > resetButtons ( ) ;
2014-08-21 16:18:56 +04:00
for ( int32 i = 0 ; i < OverviewCount ; + + i ) {
if ( mask & ( 1 < < i ) ) {
switch ( i ) {
2016-04-13 00:31:28 +03:00
case OverviewPhotos : connect ( _mediaType - > addButton ( new IconedButton ( this , st : : dropdownMediaPhotos , lang ( lng_media_type_photos ) ) ) , SIGNAL ( clicked ( ) ) , this , SLOT ( onPhotosSelect ( ) ) ) ; break ;
case OverviewVideos : connect ( _mediaType - > addButton ( new IconedButton ( this , st : : dropdownMediaVideos , lang ( lng_media_type_videos ) ) ) , SIGNAL ( clicked ( ) ) , this , SLOT ( onVideosSelect ( ) ) ) ; break ;
case OverviewMusicFiles : connect ( _mediaType - > addButton ( new IconedButton ( this , st : : dropdownMediaSongs , lang ( lng_media_type_songs ) ) ) , SIGNAL ( clicked ( ) ) , this , SLOT ( onSongsSelect ( ) ) ) ; break ;
case OverviewFiles : connect ( _mediaType - > addButton ( new IconedButton ( this , st : : dropdownMediaDocuments , lang ( lng_media_type_files ) ) ) , SIGNAL ( clicked ( ) ) , this , SLOT ( onDocumentsSelect ( ) ) ) ; break ;
case OverviewVoiceFiles : connect ( _mediaType - > addButton ( new IconedButton ( this , st : : dropdownMediaAudios , lang ( lng_media_type_audios ) ) ) , SIGNAL ( clicked ( ) ) , this , SLOT ( onAudiosSelect ( ) ) ) ; break ;
case OverviewLinks : connect ( _mediaType - > addButton ( new IconedButton ( this , st : : dropdownMediaLinks , lang ( lng_media_type_links ) ) ) , SIGNAL ( clicked ( ) ) , this , SLOT ( onLinksSelect ( ) ) ) ; break ;
2014-08-21 16:18:56 +04:00
}
}
}
_mediaTypeMask = mask ;
2016-04-13 00:31:28 +03:00
_mediaType - > move ( width ( ) - _mediaType - > width ( ) , st : : topBarHeight ) ;
_overview - > updateTopBarSelection ( ) ;
2014-08-21 16:18:56 +04:00
}
}
2014-08-15 15:19:32 +04:00
}
2014-08-20 23:13:00 +04:00
void MainWidget : : changingMsgId ( HistoryItem * row , MsgId newId ) {
2016-04-13 00:31:28 +03:00
if ( _overview ) _overview - > changingMsgId ( row , newId ) ;
2014-08-20 23:13:00 +04:00
}
2014-10-10 16:46:20 +04:00
void MainWidget : : itemRemoved ( HistoryItem * item ) {
2016-04-13 00:31:28 +03:00
_dialogs - > itemRemoved ( item ) ;
if ( _history - > peer ( ) = = item - > history ( ) - > peer | | ( _history - > peer ( ) & & _history - > peer ( ) = = item - > history ( ) - > peer - > migrateTo ( ) ) ) {
_history - > itemRemoved ( item ) ;
2014-10-10 16:46:20 +04:00
}
2016-04-13 00:31:28 +03:00
if ( _overview & & ( _overview - > peer ( ) = = item - > history ( ) - > peer | | ( _overview - > peer ( ) & & _overview - > peer ( ) = = item - > history ( ) - > peer - > migrateTo ( ) ) ) ) {
_overview - > itemRemoved ( item ) ;
2015-08-28 18:15:56 +03:00
}
2015-03-24 13:00:27 +03:00
if ( ! _toForward . isEmpty ( ) ) {
SelectedItemSet : : iterator i = _toForward . find ( item - > id ) ;
2015-11-13 18:14:33 +03:00
if ( i ! = _toForward . cend ( ) & & i . value ( ) = = item ) {
2015-03-24 13:00:27 +03:00
_toForward . erase ( i ) ;
updateForwardingTexts ( ) ;
2015-11-13 18:14:33 +03:00
} else {
i = _toForward . find ( item - > id - ServerMaxMsgId ) ;
if ( i ! = _toForward . cend ( ) & & i . value ( ) = = item ) {
_toForward . erase ( i ) ;
updateForwardingTexts ( ) ;
}
2015-03-24 13:00:27 +03:00
}
}
2014-10-10 16:46:20 +04:00
}
2016-03-11 15:20:58 +03:00
void MainWidget : : itemEdited ( HistoryItem * item ) {
2016-04-13 00:31:28 +03:00
if ( _history - > peer ( ) = = item - > history ( ) - > peer | | ( _history - > peer ( ) & & _history - > peer ( ) = = item - > history ( ) - > peer - > migrateTo ( ) ) ) {
_history - > itemEdited ( item ) ;
2016-03-11 15:20:58 +03:00
}
}
2014-08-15 15:19:32 +04:00
bool MainWidget : : overviewFailed ( PeerData * peer , const RPCError & error , mtpRequestId req ) {
2016-04-08 14:44:35 +04:00
if ( MTP : : isDefaultHandledError ( error ) ) return false ;
2015-04-04 23:01:34 +03:00
2014-08-15 15:19:32 +04:00
MediaOverviewType type = OverviewCount ;
for ( int32 i = 0 ; i < OverviewCount ; + + i ) {
OverviewsPreload : : iterator j = _overviewPreload [ i ] . find ( peer ) ;
if ( j ! = _overviewPreload [ i ] . end ( ) & & j . value ( ) = = req ) {
_overviewPreload [ i ] . erase ( j ) ;
break ;
}
}
return true ;
}
void MainWidget : : loadMediaBack ( PeerData * peer , MediaOverviewType type , bool many ) {
if ( _overviewLoad [ type ] . constFind ( peer ) ! = _overviewLoad [ type ] . cend ( ) ) return ;
2015-11-18 16:11:56 +03:00
History * history = App : : history ( peer - > id ) ;
if ( history - > overviewLoaded ( type ) ) return ;
2014-08-15 15:19:32 +04:00
2015-11-18 16:11:56 +03:00
MsgId minId = history - > overviewMinId ( type ) ;
2015-12-23 14:13:08 +03:00
int32 limit = ( many | | history - > overview [ type ] . size ( ) > MediaOverviewStartPerPage ) ? SearchPerPage : MediaOverviewStartPerPage ;
2014-08-15 15:19:32 +04:00
MTPMessagesFilter filter = typeToMediaFilter ( type ) ;
if ( type = = OverviewCount ) return ;
2016-03-19 19:55:15 +03:00
MTPmessages_Search : : Flags flags = 0 ;
if ( peer - > isChannel ( ) & & ! peer - > isMegagroup ( ) ) {
flags | = MTPmessages_Search : : Flag : : f_important_only ;
}
_overviewLoad [ type ] . insert ( peer , MTP : : send ( MTPmessages_Search ( MTP_flags ( flags ) , peer - > input , MTPstring ( ) , filter , MTP_int ( 0 ) , MTP_int ( 0 ) , MTP_int ( 0 ) , MTP_int ( minId ) , MTP_int ( limit ) ) , rpcDone ( & MainWidget : : overviewLoaded , history ) ) ) ;
2014-08-15 15:19:32 +04:00
}
2014-11-12 23:30:26 +03:00
void MainWidget : : checkLastUpdate ( bool afterSleep ) {
uint64 n = getms ( true ) ;
if ( _lastUpdateTime & & n > _lastUpdateTime + ( afterSleep ? NoUpdatesAfterSleepTimeout : NoUpdatesTimeout ) ) {
2015-04-16 17:59:42 +03:00
_lastUpdateTime = n ;
MTP : : ping ( ) ;
2014-11-12 23:30:26 +03:00
}
}
2014-11-25 15:15:29 +03:00
void MainWidget : : showAddContact ( ) {
2016-04-13 00:31:28 +03:00
_dialogs - > onAddContact ( ) ;
2014-11-25 15:15:29 +03:00
}
2014-11-18 15:40:43 +03:00
void MainWidget : : showNewGroup ( ) {
2016-04-13 00:31:28 +03:00
_dialogs - > onNewGroup ( ) ;
2014-11-18 15:40:43 +03:00
}
2015-11-18 16:11:56 +03:00
void MainWidget : : overviewLoaded ( History * history , const MTPmessages_Messages & result , mtpRequestId req ) {
2014-08-15 15:19:32 +04:00
OverviewsPreload : : iterator it ;
MediaOverviewType type = OverviewCount ;
for ( int32 i = 0 ; i < OverviewCount ; + + i ) {
2015-11-18 16:11:56 +03:00
it = _overviewLoad [ i ] . find ( history - > peer ) ;
2014-08-15 15:19:32 +04:00
if ( it ! = _overviewLoad [ i ] . cend ( ) ) {
type = MediaOverviewType ( i ) ;
_overviewLoad [ i ] . erase ( it ) ;
break ;
}
}
if ( type = = OverviewCount ) return ;
2015-11-18 16:11:56 +03:00
history - > overviewSliceDone ( type , result ) ;
2014-08-15 15:19:32 +04:00
2015-11-18 16:11:56 +03:00
if ( App : : wnd ( ) ) App : : wnd ( ) - > mediaOverviewUpdated ( history - > peer , type ) ;
2014-08-15 15:19:32 +04:00
}
2015-09-06 13:17:09 +03:00
void MainWidget : : sendReadRequest ( PeerData * peer , MsgId upTo ) {
if ( ! MTP : : authedId ( ) ) return ;
if ( peer - > isChannel ( ) ) {
2016-03-22 18:23:34 +03:00
_readRequests . insert ( peer , qMakePair ( MTP : : send ( MTPchannels_ReadHistory ( peer - > asChannel ( ) - > inputChannel , MTP_int ( upTo ) ) , rpcDone ( & MainWidget : : channelWasRead , peer ) , rpcFail ( & MainWidget : : readRequestFail , peer ) ) , upTo ) ) ;
2015-09-06 13:17:09 +03:00
} else {
2016-03-22 18:23:34 +03:00
_readRequests . insert ( peer , qMakePair ( MTP : : send ( MTPmessages_ReadHistory ( peer - > input , MTP_int ( upTo ) ) , rpcDone ( & MainWidget : : historyWasRead , peer ) , rpcFail ( & MainWidget : : readRequestFail , peer ) ) , upTo ) ) ;
2015-09-06 13:17:09 +03:00
}
}
void MainWidget : : channelWasRead ( PeerData * peer , const MTPBool & result ) {
readRequestDone ( peer ) ;
}
2015-10-29 15:10:49 -04:00
void MainWidget : : historyWasRead ( PeerData * peer , const MTPmessages_AffectedMessages & result ) {
messagesAffected ( peer , result ) ;
readRequestDone ( peer ) ;
2014-06-15 16:31:03 +04:00
}
2015-09-06 13:17:09 +03:00
bool MainWidget : : readRequestFail ( PeerData * peer , const RPCError & error ) {
2016-04-08 14:44:35 +04:00
if ( MTP : : isDefaultHandledError ( error ) ) return false ;
2015-09-06 13:17:09 +03:00
readRequestDone ( peer ) ;
return false ;
}
void MainWidget : : readRequestDone ( PeerData * peer ) {
_readRequests . remove ( peer ) ;
ReadRequestsPending : : iterator i = _readRequestsPending . find ( peer ) ;
if ( i ! = _readRequestsPending . cend ( ) ) {
sendReadRequest ( peer , i . value ( ) ) ;
_readRequestsPending . erase ( i ) ;
}
}
2015-09-07 10:52:37 +03:00
void MainWidget : : messagesAffected ( PeerData * peer , const MTPmessages_AffectedMessages & result ) {
2016-04-08 14:44:35 +04:00
const auto & d ( result . c_messages_affectedMessages ( ) ) ;
2015-09-07 10:52:37 +03:00
if ( peer & & peer - > isChannel ( ) ) {
2015-09-20 12:54:22 +03:00
if ( peer - > asChannel ( ) - > ptsUpdated ( d . vpts . v , d . vpts_count . v ) ) {
peer - > asChannel ( ) - > ptsApplySkippedUpdates ( ) ;
2016-05-25 15:09:05 +03:00
Notify : : peerUpdatedSendDelayed ( ) ;
2015-09-20 12:54:22 +03:00
}
2015-09-07 10:52:37 +03:00
} else {
2015-09-20 12:54:22 +03:00
if ( ptsUpdated ( d . vpts . v , d . vpts_count . v ) ) {
ptsApplySkippedUpdates ( ) ;
2016-05-25 15:09:05 +03:00
Notify : : peerUpdatedSendDelayed ( ) ;
2015-09-20 12:54:22 +03:00
}
2015-09-07 10:52:37 +03:00
}
2015-09-23 20:43:08 +03:00
if ( History * h = App : : historyLoaded ( peer ? peer - > id : 0 ) ) {
2015-09-19 12:13:21 +03:00
if ( ! h - > lastMsg ) {
checkPeerHistory ( peer ) ;
}
}
2015-03-19 12:18:19 +03:00
}
2014-05-30 12:53:19 +04:00
void MainWidget : : loadFailed ( mtpFileLoader * loader , bool started , const char * retrySlot ) {
failedObjId = loader - > objId ( ) ;
failedFileName = loader - > fileName ( ) ;
ConfirmBox * box = new ConfirmBox ( lang ( started ? lng_download_finish_failed : lng_download_path_failed ) , started ? QString ( ) : lang ( lng_download_path_settings ) ) ;
if ( started ) {
connect ( box , SIGNAL ( confirmed ( ) ) , this , retrySlot ) ;
} else {
2015-11-26 20:34:52 +03:00
connect ( box , SIGNAL ( confirmed ( ) ) , this , SLOT ( onDownloadPathSettings ( ) ) ) ;
}
2015-12-07 21:09:05 +03:00
Ui : : showLayer ( box ) ;
2015-11-26 20:34:52 +03:00
}
void MainWidget : : onDownloadPathSettings ( ) {
cSetDownloadPath ( QString ( ) ) ;
cSetDownloadPathBookmark ( QByteArray ( ) ) ;
DownloadPathBox * box = new DownloadPathBox ( ) ;
if ( App : : wnd ( ) & & App : : wnd ( ) - > settingsWidget ( ) ) {
connect ( box , SIGNAL ( closed ( ) ) , App : : wnd ( ) - > settingsWidget ( ) , SLOT ( onDownloadPathEdited ( ) ) ) ;
2014-05-30 12:53:19 +04:00
}
2015-12-07 21:09:05 +03:00
Ui : : showLayer ( box ) ;
2014-05-30 12:53:19 +04:00
}
2016-03-30 20:42:01 +04:00
void MainWidget : : onSharePhoneWithBot ( PeerData * recipient ) {
onShareContact ( recipient - > id , App : : self ( ) ) ;
}
2015-12-13 14:17:15 +03:00
void MainWidget : : ui_showPeerHistoryAsync ( quint64 peerId , qint32 showAtMsgId ) {
Ui : : showPeerHistory ( peerId , showAtMsgId ) ;
}
2016-03-19 19:55:15 +03:00
void MainWidget : : ui_autoplayMediaInlineAsync ( qint32 channelId , qint32 msgId ) {
if ( HistoryItem * item = App : : histItemById ( channelId , msgId ) ) {
if ( HistoryMedia * media = item - > getMedia ( ) ) {
2016-04-10 18:53:01 +04:00
media - > playInline ( true ) ;
2016-03-19 19:55:15 +03:00
}
}
}
2015-07-01 00:07:05 +03:00
void MainWidget : : audioPlayProgress ( const AudioMsgId & audioId ) {
AudioMsgId playing ;
2015-05-29 21:52:43 +03:00
AudioPlayerState state = AudioPlayerStopped ;
audioPlayer ( ) - > currentState ( & playing , & state ) ;
2015-07-01 00:07:05 +03:00
if ( playing = = audioId & & state = = AudioPlayerStoppedAtStart ) {
audioPlayer ( ) - > clearStoppedAtStart ( audioId ) ;
2016-02-12 19:35:06 +03:00
DocumentData * audio = audioId . audio ;
2016-03-16 14:54:37 +03:00
QString filepath = audio - > filepath ( DocumentData : : FilePathResolveSaveFromData ) ;
if ( ! filepath . isEmpty ( ) ) {
psOpenFile ( filepath ) ;
2015-05-24 20:58:39 +03:00
}
}
2016-04-10 22:18:26 +04:00
if ( HistoryItem * item = App : : histItemById ( audioId . contextId ) ) {
2015-12-28 00:37:48 +03:00
Ui : : repaintHistoryItem ( item ) ;
2015-07-01 00:07:05 +03:00
}
2016-04-10 22:18:26 +04:00
if ( auto items = InlineBots : : Layout : : documentItems ( ) ) {
for ( auto item : items - > value ( audioId . audio ) ) {
Ui : : repaintInlineItem ( item ) ;
}
}
2015-07-01 00:07:05 +03:00
}
void MainWidget : : documentPlayProgress ( const SongMsgId & songId ) {
SongMsgId playing ;
2015-07-03 11:47:16 +03:00
AudioPlayerState playingState = AudioPlayerStopped ;
int64 playingPosition = 0 , playingDuration = 0 ;
int32 playingFrequency = 0 ;
audioPlayer ( ) - > currentState ( & playing , & playingState , & playingPosition , & playingDuration , & playingFrequency ) ;
if ( playing = = songId & & playingState = = AudioPlayerStoppedAtStart ) {
playingState = AudioPlayerStopped ;
2015-07-01 00:07:05 +03:00
audioPlayer ( ) - > clearStoppedAtStart ( songId ) ;
DocumentData * document = songId . song ;
2016-03-16 14:54:37 +03:00
QString filepath = document - > filepath ( DocumentData : : FilePathResolveSaveFromData ) ;
if ( ! filepath . isEmpty ( ) ) {
psOpenFile ( filepath ) ;
2015-07-01 00:07:05 +03:00
}
}
2015-07-03 11:47:16 +03:00
if ( playing = = songId ) {
2016-04-13 00:31:28 +03:00
_player - > updateState ( playing , playingState , playingPosition , playingDuration , playingFrequency ) ;
2015-07-03 11:47:16 +03:00
2016-04-14 19:08:36 +03:00
if ( ! ( playingState & AudioPlayerStoppedMask ) & & playingState ! = AudioPlayerFinishing ) {
if ( ! _player - > isOpened ( ) ) {
_player - > openPlayer ( ) ;
if ( _player - > isHidden ( ) & & ! _a_show . animating ( ) ) {
_player - > showPlayer ( ) ;
_playerHeight = _contentScrollAddToY = _player - > height ( ) ;
resizeEvent ( 0 ) ;
}
2015-07-03 11:47:16 +03:00
}
}
}
2016-04-10 22:18:26 +04:00
if ( HistoryItem * item = App : : histItemById ( songId . contextId ) ) {
2015-12-28 00:37:48 +03:00
Ui : : repaintHistoryItem ( item ) ;
2014-09-04 11:33:44 +04:00
}
2016-04-10 22:18:26 +04:00
if ( auto items = InlineBots : : Layout : : documentItems ( ) ) {
for ( auto item : items - > value ( songId . song ) ) {
Ui : : repaintInlineItem ( item ) ;
}
}
2014-09-04 11:33:44 +04:00
}
2016-04-14 19:08:36 +03:00
void MainWidget : : closePlayer ( ) {
if ( _player - > isOpened ( ) ) {
_player - > closePlayer ( ) ;
if ( ! _player - > isHidden ( ) & & ! _a_show . animating ( ) ) {
_player - > hidePlayer ( ) ;
_contentScrollAddToY = - _player - > height ( ) ;
_playerHeight = 0 ;
resizeEvent ( 0 ) ;
}
2015-07-03 11:47:16 +03:00
}
}
2015-12-31 03:09:20 +08:00
void MainWidget : : documentLoadProgress ( FileLoader * loader ) {
mtpFileLoader * l = loader ? loader - > mtpLoader ( ) : 0 ;
if ( ! l ) return ;
DocumentData * document = App : : document ( l - > objId ( ) ) ;
2015-12-24 22:26:28 +03:00
if ( document - > loaded ( ) ) {
document - > performActionOnLoad ( ) ;
2014-05-30 12:53:19 +04:00
}
2015-12-24 22:26:28 +03:00
2014-05-30 12:53:19 +04:00
const DocumentItems & items ( App : : documentItems ( ) ) ;
DocumentItems : : const_iterator i = items . constFind ( document ) ;
if ( i ! = items . cend ( ) ) {
for ( HistoryItemsMap : : const_iterator j = i - > cbegin ( ) , e = i - > cend ( ) ; j ! = e ; + + j ) {
2015-12-28 00:37:48 +03:00
Ui : : repaintHistoryItem ( j . key ( ) ) ;
2014-05-30 12:53:19 +04:00
}
}
2015-04-19 13:29:19 +03:00
App : : wnd ( ) - > documentUpdated ( document ) ;
2015-07-03 11:47:16 +03:00
2015-12-24 22:26:28 +03:00
if ( ! document - > loaded ( ) & & document - > loading ( ) & & document - > song ( ) & & audioPlayer ( ) ) {
2015-07-03 11:47:16 +03:00
SongMsgId playing ;
AudioPlayerState playingState = AudioPlayerStopped ;
int64 playingPosition = 0 , playingDuration = 0 ;
int32 playingFrequency = 0 ;
audioPlayer ( ) - > currentState ( & playing , & playingState , & playingPosition , & playingDuration , & playingFrequency ) ;
2016-04-13 00:31:28 +03:00
if ( playing . song = = document & & ! _player - > isHidden ( ) ) {
_player - > updateState ( playing , playingState , playingPosition , playingDuration , playingFrequency ) ;
2015-07-03 11:47:16 +03:00
}
}
2014-05-30 12:53:19 +04:00
}
2015-12-31 03:09:20 +08:00
void MainWidget : : documentLoadFailed ( FileLoader * loader , bool started ) {
mtpFileLoader * l = loader ? loader - > mtpLoader ( ) : 0 ;
if ( ! l ) return ;
loadFailed ( l , started , SLOT ( documentLoadRetry ( ) ) ) ;
DocumentData * document = App : : document ( l - > objId ( ) ) ;
2015-03-19 12:18:19 +03:00
if ( document ) {
2015-12-24 22:26:28 +03:00
if ( document - > loading ( ) ) document - > cancel ( ) ;
2015-12-08 22:07:50 +03:00
document - > status = FileDownloadFailed ;
2015-03-19 12:18:19 +03:00
}
2014-05-30 12:53:19 +04:00
}
void MainWidget : : documentLoadRetry ( ) {
2015-12-07 21:09:05 +03:00
Ui : : hideLayer ( ) ;
2014-05-30 12:53:19 +04:00
DocumentData * document = App : : document ( failedObjId ) ;
if ( document ) document - > save ( failedFileName ) ;
}
2015-12-31 13:34:43 +08:00
void MainWidget : : inlineResultLoadProgress ( FileLoader * loader ) {
2016-04-05 01:09:46 +04:00
//InlineBots::Result *result = InlineBots::resultFromLoader(loader);
2015-12-31 13:34:43 +08:00
//if (!result) return;
//result->loaded();
//Ui::repaintInlineItem();
}
void MainWidget : : inlineResultLoadFailed ( FileLoader * loader , bool started ) {
2016-04-05 01:09:46 +04:00
//InlineBots::Result *result = InlineBots::resultFromLoader(loader);
2015-12-31 13:34:43 +08:00
//if (!result) return;
//result->loaded();
//Ui::repaintInlineItem();
}
2016-02-12 21:18:32 +03:00
void MainWidget : : mediaMarkRead ( DocumentData * data ) {
2016-02-12 19:35:06 +03:00
const DocumentItems & items ( App : : documentItems ( ) ) ;
DocumentItems : : const_iterator i = items . constFind ( data ) ;
2015-04-30 16:53:36 +03:00
if ( i ! = items . cend ( ) ) {
mediaMarkRead ( i . value ( ) ) ;
}
}
void MainWidget : : mediaMarkRead ( const HistoryItemsMap & items ) {
QVector < MTPint > markedIds ;
markedIds . reserve ( items . size ( ) ) ;
for ( HistoryItemsMap : : const_iterator j = items . cbegin ( ) , e = items . cend ( ) ; j ! = e ; + + j ) {
if ( ! j . key ( ) - > out ( ) & & j . key ( ) - > isMediaUnread ( ) ) {
j . key ( ) - > markMediaRead ( ) ;
if ( j . key ( ) - > id > 0 ) {
markedIds . push_back ( MTP_int ( j . key ( ) - > id ) ) ;
}
}
}
if ( ! markedIds . isEmpty ( ) ) {
2015-09-07 10:52:37 +03:00
MTP : : send ( MTPmessages_ReadMessageContents ( MTP_vector < MTPint > ( markedIds ) ) , rpcDone ( & MainWidget : : messagesAffected , ( PeerData * ) 0 ) ) ;
2015-04-30 16:53:36 +03:00
}
}
2014-05-30 12:53:19 +04:00
void MainWidget : : onParentResize ( const QSize & newSize ) {
resize ( newSize ) ;
}
void MainWidget : : updateOnlineDisplay ( ) {
2015-03-02 15:34:16 +03:00
if ( this ! = App : : main ( ) ) return ;
2016-04-13 00:31:28 +03:00
_history - > updateOnlineDisplay ( _history - > x ( ) , width ( ) - _history - > x ( ) - st : : sysBtnDelta * 2 - st : : sysCls . img . pxWidth ( ) - st : : sysRes . img . pxWidth ( ) - st : : sysMin . img . pxWidth ( ) ) ;
2016-05-12 19:05:20 +03:00
// if (_profile) _profile->updateOnlineDisplay(); TODO
2014-05-30 12:53:19 +04:00
if ( App : : wnd ( ) - > settingsWidget ( ) ) App : : wnd ( ) - > settingsWidget ( ) - > updateOnlineDisplay ( ) ;
}
2015-10-26 22:39:02 -04:00
void MainWidget : : onSendFileConfirm ( const FileLoadResultPtr & file , bool ctrlShiftEnter ) {
2016-04-13 00:31:28 +03:00
bool lastKeyboardUsed = _history - > lastForceReplyReplied ( FullMsgId ( peerToChannel ( file - > to . peer ) , file - > to . replyTo ) ) ;
_history - > confirmSendFile ( file , ctrlShiftEnter ) ;
_history - > cancelReply ( lastKeyboardUsed ) ;
2015-10-26 22:39:02 -04:00
}
void MainWidget : : onSendFileCancel ( const FileLoadResultPtr & file ) {
2016-04-13 00:31:28 +03:00
_history - > cancelSendFile ( file ) ;
2015-10-26 22:39:02 -04:00
}
2015-10-27 22:41:13 -04:00
void MainWidget : : onShareContactConfirm ( const QString & phone , const QString & fname , const QString & lname , MsgId replyTo , bool ctrlShiftEnter ) {
2016-04-13 00:31:28 +03:00
_history - > confirmShareContact ( phone , fname , lname , replyTo , ctrlShiftEnter ) ;
2014-08-11 13:03:45 +04:00
}
2015-10-27 22:41:13 -04:00
void MainWidget : : onShareContactCancel ( ) {
2016-04-13 00:31:28 +03:00
_history - > cancelShareContact ( ) ;
2014-05-30 12:53:19 +04:00
}
void MainWidget : : dialogsCancelled ( ) {
2015-07-17 22:17:37 +03:00
if ( _hider ) {
_hider - > startHide ( ) ;
noHider ( _hider ) ;
2014-05-30 12:53:19 +04:00
}
2016-04-13 00:31:28 +03:00
_history - > activate ( ) ;
2014-05-30 12:53:19 +04:00
}
2015-09-20 11:55:41 +03:00
void MainWidget : : serviceNotification ( const QString & msg , const MTPMessageMedia & media ) {
2016-03-19 19:55:15 +03:00
MTPDmessage : : Flags flags = MTPDmessage : : Flag : : f_unread | MTPDmessage : : Flag : : f_entities | MTPDmessage : : Flag : : f_from_id ;
2015-02-20 18:41:54 +03:00
QString sendingText , leftText = msg ;
2016-04-30 20:04:14 +03:00
EntitiesInText sendingEntities , leftEntities ;
textParseEntities ( leftText , _historyTextNoMonoOptions . flags , & leftEntities ) ;
2015-02-20 18:41:54 +03:00
HistoryItem * item = 0 ;
2015-10-23 18:06:56 +02:00
while ( textSplit ( sendingText , sendingEntities , leftText , leftEntities , MaxMessageSize ) ) {
MTPVector < MTPMessageEntity > localEntities = linksToMTP ( sendingEntities ) ;
2016-03-19 19:55:15 +03:00
item = App : : histories ( ) . addNewMessage ( MTP_message ( MTP_flags ( flags ) , MTP_int ( clientMsgId ( ) ) , MTP_int ( ServiceUserId ) , MTP_peerUser ( MTP_int ( MTP : : authedId ( ) ) ) , MTPnullFwdHeader , MTPint ( ) , MTPint ( ) , MTP_int ( unixtime ( ) ) , MTP_string ( sendingText ) , media , MTPnullMarkup , localEntities , MTPint ( ) , MTPint ( ) ) , NewMessageUnread ) ;
2015-02-20 18:41:54 +03:00
}
2014-12-12 19:27:03 +03:00
if ( item ) {
2016-04-13 00:31:28 +03:00
_history - > peerMessagesUpdated ( item - > history ( ) - > peer - > id ) ;
2014-12-12 19:27:03 +03:00
}
}
void MainWidget : : serviceHistoryDone ( const MTPmessages_Messages & msgs ) {
switch ( msgs . type ( ) ) {
2015-09-04 16:01:31 +03:00
case mtpc_messages_messages : {
2016-04-08 14:44:35 +04:00
const auto & d ( msgs . c_messages_messages ( ) ) ;
2015-09-04 16:01:31 +03:00
App : : feedUsers ( d . vusers ) ;
App : : feedChats ( d . vchats ) ;
2015-09-20 11:55:41 +03:00
App : : feedMsgs ( d . vmessages , NewMessageLast ) ;
2015-09-04 16:01:31 +03:00
} break ;
case mtpc_messages_messagesSlice : {
2016-04-08 14:44:35 +04:00
const auto & d ( msgs . c_messages_messagesSlice ( ) ) ;
2015-09-04 16:01:31 +03:00
App : : feedUsers ( d . vusers ) ;
App : : feedChats ( d . vchats ) ;
2015-09-20 11:55:41 +03:00
App : : feedMsgs ( d . vmessages , NewMessageLast ) ;
2015-09-04 16:01:31 +03:00
} break ;
2014-12-12 19:27:03 +03:00
2015-09-04 16:01:31 +03:00
case mtpc_messages_channelMessages : {
2016-04-08 14:44:35 +04:00
const auto & d ( msgs . c_messages_channelMessages ( ) ) ;
2015-09-19 12:13:21 +03:00
LOG ( ( " API Error: received messages.channelMessages! (MainWidget::serviceHistoryDone) " ) ) ;
if ( d . has_collapsed ( ) ) { // should not be returned
LOG ( ( " API Error: channels.getMessages and messages.getMessages should not return collapsed groups! (MainWidget::serviceHistoryDone) " ) ) ;
}
2015-09-13 11:41:27 +03:00
2015-09-04 16:01:31 +03:00
App : : feedUsers ( d . vusers ) ;
App : : feedChats ( d . vchats ) ;
2015-09-20 11:55:41 +03:00
App : : feedMsgs ( d . vmessages , NewMessageLast ) ;
2015-09-04 16:01:31 +03:00
} break ;
2014-12-12 19:27:03 +03:00
}
App : : wnd ( ) - > showDelayedServiceMsgs ( ) ;
}
bool MainWidget : : serviceHistoryFail ( const RPCError & error ) {
2016-04-08 14:44:35 +04:00
if ( MTP : : isDefaultHandledError ( error ) ) return false ;
2015-04-04 23:01:34 +03:00
2014-12-12 19:27:03 +03:00
App : : wnd ( ) - > showDelayedServiceMsgs ( ) ;
return false ;
}
2015-01-26 16:04:41 +03:00
bool MainWidget : : isIdle ( ) const {
return _isIdle ;
}
2015-02-03 18:02:46 +03:00
void MainWidget : : clearCachedBackground ( ) {
_cachedBackground = QPixmap ( ) ;
_cacheBackgroundTimer . stop ( ) ;
}
QPixmap MainWidget : : cachedBackground ( const QRect & forRect , int & x , int & y ) {
if ( ! _cachedBackground . isNull ( ) & & forRect = = _cachedFor ) {
x = _cachedX ;
y = _cachedY ;
return _cachedBackground ;
}
if ( _willCacheFor ! = forRect | | ! _cacheBackgroundTimer . isActive ( ) ) {
_willCacheFor = forRect ;
_cacheBackgroundTimer . start ( CacheBackgroundTimeout ) ;
}
return QPixmap ( ) ;
}
void MainWidget : : backgroundParams ( const QRect & forRect , QRect & to , QRect & from ) const {
const QSize & bg ( cChatBackground ( ) - > size ( ) ) ;
if ( uint64 ( bg . width ( ) ) * forRect . height ( ) > uint64 ( bg . height ( ) ) * forRect . width ( ) ) {
float64 pxsize = forRect . height ( ) / float64 ( bg . height ( ) ) ;
int takewidth = qCeil ( forRect . width ( ) / pxsize ) ;
if ( takewidth > bg . width ( ) ) {
takewidth = bg . width ( ) ;
} else if ( ( bg . width ( ) % 2 ) ! = ( takewidth % 2 ) ) {
+ + takewidth ;
}
to = QRect ( int ( ( forRect . width ( ) - takewidth * pxsize ) / 2. ) , 0 , qCeil ( takewidth * pxsize ) , forRect . height ( ) ) ;
from = QRect ( ( bg . width ( ) - takewidth ) / 2 , 0 , takewidth , bg . height ( ) ) ;
} else {
float64 pxsize = forRect . width ( ) / float64 ( bg . width ( ) ) ;
int takeheight = qCeil ( forRect . height ( ) / pxsize ) ;
if ( takeheight > bg . height ( ) ) {
takeheight = bg . height ( ) ;
} else if ( ( bg . height ( ) % 2 ) ! = ( takeheight % 2 ) ) {
+ + takeheight ;
}
to = QRect ( 0 , int ( ( forRect . height ( ) - takeheight * pxsize ) / 2. ) , forRect . width ( ) , qCeil ( takeheight * pxsize ) ) ;
from = QRect ( 0 , ( bg . height ( ) - takeheight ) / 2 , bg . width ( ) , takeheight ) ;
}
}
void MainWidget : : updateScrollColors ( ) {
2016-04-13 00:31:28 +03:00
_history - > updateScrollColors ( ) ;
if ( _overview ) _overview - > updateScrollColors ( ) ;
2015-02-03 18:02:46 +03:00
}
void MainWidget : : setChatBackground ( const App : : WallPaper & wp ) {
2016-04-13 00:31:28 +03:00
_background = std_ : : make_unique < App : : WallPaper > ( wp ) ;
2015-12-24 22:26:28 +03:00
_background - > full - > loadEvenCancelled ( ) ;
2015-02-03 18:02:46 +03:00
checkChatBackground ( ) ;
}
bool MainWidget : : chatBackgroundLoading ( ) {
return ! ! _background ;
}
void MainWidget : : checkChatBackground ( ) {
if ( _background ) {
if ( _background - > full - > loaded ( ) ) {
if ( _background - > full - > isNull ( ) ) {
App : : initBackground ( ) ;
2015-04-23 18:50:11 +03:00
} else if ( _background - > id = = 0 | | _background - > id = = DefaultChatBackground ) {
App : : initBackground ( _background - > id ) ;
2015-02-03 18:02:46 +03:00
} else {
2015-04-23 18:50:11 +03:00
App : : initBackground ( _background - > id , _background - > full - > pix ( ) . toImage ( ) ) ;
2015-02-03 18:02:46 +03:00
}
2016-04-13 00:31:28 +03:00
_background = nullptr ;
2015-02-03 18:02:46 +03:00
QTimer : : singleShot ( 0 , this , SLOT ( update ( ) ) ) ;
}
}
}
ImagePtr MainWidget : : newBackgroundThumb ( ) {
return _background ? _background - > thumb : ImagePtr ( ) ;
}
2015-03-19 12:18:19 +03:00
ApiWrap * MainWidget : : api ( ) {
2016-04-13 00:31:28 +03:00
return _api . get ( ) ;
2015-03-19 12:18:19 +03:00
}
2016-03-10 13:15:21 +03:00
void MainWidget : : messageDataReceived ( ChannelData * channel , MsgId msgId ) {
2016-04-13 00:31:28 +03:00
_history - > messageDataReceived ( channel , msgId ) ;
2015-03-19 12:18:19 +03:00
}
2015-11-24 19:19:18 +03:00
void MainWidget : : updateBotKeyboard ( History * h ) {
2016-04-13 00:31:28 +03:00
_history - > updateBotKeyboard ( h ) ;
2015-06-18 20:24:54 +03:00
}
2015-03-24 13:00:27 +03:00
void MainWidget : : pushReplyReturn ( HistoryItem * item ) {
2016-04-13 00:31:28 +03:00
_history - > pushReplyReturn ( item ) ;
2015-03-24 13:00:27 +03:00
}
2014-05-30 12:53:19 +04:00
void MainWidget : : setInnerFocus ( ) {
2016-04-13 00:31:28 +03:00
if ( _hider | | ! _history - > peer ( ) ) {
2015-07-17 22:17:37 +03:00
if ( _hider & & _hider - > wasOffered ( ) ) {
_hider - > setFocus ( ) ;
2016-04-13 00:31:28 +03:00
} else if ( _overview ) {
_overview - > activate ( ) ;
2016-05-19 15:03:51 +03:00
} else if ( _wideSection ) {
_wideSection - > setInnerFocus ( ) ;
2014-05-30 12:53:19 +04:00
} else {
2015-07-17 22:17:37 +03:00
dialogsActivate ( ) ;
2014-05-30 12:53:19 +04:00
}
2016-04-13 00:31:28 +03:00
} else if ( _overview ) {
_overview - > activate ( ) ;
2016-05-19 15:03:51 +03:00
} else if ( _wideSection ) {
_wideSection - > setInnerFocus ( ) ;
2014-05-30 12:53:19 +04:00
} else {
2016-04-13 00:31:28 +03:00
_history - > setInnerFocus ( ) ;
2014-05-30 12:53:19 +04:00
}
}
2015-09-21 23:57:42 +03:00
void MainWidget : : scheduleViewIncrement ( HistoryItem * item ) {
PeerData * peer = item - > history ( ) - > peer ;
ViewsIncrement : : iterator i = _viewsIncremented . find ( peer ) ;
if ( i ! = _viewsIncremented . cend ( ) ) {
if ( i . value ( ) . contains ( item - > id ) ) return ;
} else {
i = _viewsIncremented . insert ( peer , ViewsIncrementMap ( ) ) ;
}
i . value ( ) . insert ( item - > id , true ) ;
ViewsIncrement : : iterator j = _viewsToIncrement . find ( peer ) ;
if ( j = = _viewsToIncrement . cend ( ) ) {
j = _viewsToIncrement . insert ( peer , ViewsIncrementMap ( ) ) ;
_viewsIncrementTimer . start ( SendViewsTimeout ) ;
}
j . value ( ) . insert ( item - > id , true ) ;
}
void MainWidget : : onViewsIncrement ( ) {
2016-03-15 21:08:17 +03:00
if ( ! App : : main ( ) | | ! MTP : : authedId ( ) ) return ;
2015-09-21 23:57:42 +03:00
for ( ViewsIncrement : : iterator i = _viewsToIncrement . begin ( ) ; i ! = _viewsToIncrement . cend ( ) ; ) {
if ( _viewsIncrementRequests . contains ( i . key ( ) ) ) {
+ + i ;
continue ;
}
QVector < MTPint > ids ;
ids . reserve ( i . value ( ) . size ( ) ) ;
for ( ViewsIncrementMap : : const_iterator j = i . value ( ) . cbegin ( ) , end = i . value ( ) . cend ( ) ; j ! = end ; + + j ) {
ids . push_back ( MTP_int ( j . key ( ) ) ) ;
}
mtpRequestId req = MTP : : send ( MTPmessages_GetMessagesViews ( i . key ( ) - > input , MTP_vector < MTPint > ( ids ) , MTP_bool ( true ) ) , rpcDone ( & MainWidget : : viewsIncrementDone , ids ) , rpcFail ( & MainWidget : : viewsIncrementFail ) , 0 , 5 ) ;
_viewsIncrementRequests . insert ( i . key ( ) , req ) ;
i = _viewsToIncrement . erase ( i ) ;
}
}
void MainWidget : : viewsIncrementDone ( QVector < MTPint > ids , const MTPVector < MTPint > & result , mtpRequestId req ) {
2016-04-08 14:44:35 +04:00
const auto & v ( result . c_vector ( ) . v ) ;
2015-09-21 23:57:42 +03:00
if ( ids . size ( ) = = v . size ( ) ) {
for ( ViewsIncrementRequests : : iterator i = _viewsIncrementRequests . begin ( ) ; i ! = _viewsIncrementRequests . cend ( ) ; + + i ) {
if ( i . value ( ) = = req ) {
PeerData * peer = i . key ( ) ;
ChannelId channel = peerToChannel ( peer - > id ) ;
for ( int32 j = 0 , l = ids . size ( ) ; j < l ; + + j ) {
if ( HistoryItem * item = App : : histItemById ( channel , ids . at ( j ) . v ) ) {
item - > setViewsCount ( v . at ( j ) . v ) ;
}
}
_viewsIncrementRequests . erase ( i ) ;
break ;
}
}
}
if ( ! _viewsToIncrement . isEmpty ( ) & & ! _viewsIncrementTimer . isActive ( ) ) {
_viewsIncrementTimer . start ( SendViewsTimeout ) ;
}
}
bool MainWidget : : viewsIncrementFail ( const RPCError & error , mtpRequestId req ) {
2016-04-08 14:44:35 +04:00
if ( MTP : : isDefaultHandledError ( error ) ) return false ;
2015-09-21 23:57:42 +03:00
for ( ViewsIncrementRequests : : iterator i = _viewsIncrementRequests . begin ( ) ; i ! = _viewsIncrementRequests . cend ( ) ; + + i ) {
if ( i . value ( ) = = req ) {
_viewsIncrementRequests . erase ( i ) ;
break ;
}
}
if ( ! _viewsToIncrement . isEmpty ( ) & & ! _viewsIncrementTimer . isActive ( ) ) {
_viewsIncrementTimer . start ( SendViewsTimeout ) ;
}
return false ;
}
2015-09-19 12:13:21 +03:00
HistoryItem * MainWidget : : atTopImportantMsg ( int32 & bottomUnderScrollTop ) const {
2016-04-13 00:31:28 +03:00
return _history - > atTopImportantMsg ( bottomUnderScrollTop ) ;
2015-09-19 12:13:21 +03:00
}
2015-09-21 23:57:42 +03:00
void MainWidget : : createDialog ( History * history ) {
2016-04-13 00:31:28 +03:00
_dialogs - > createDialog ( history ) ;
2014-05-30 12:53:19 +04:00
}
2015-07-17 22:17:37 +03:00
void MainWidget : : choosePeer ( PeerId peerId , MsgId showAtMsgId ) {
if ( selectingPeer ( ) ) {
offerPeer ( peerId ) ;
} else {
2015-12-13 14:36:08 +03:00
Ui : : showPeerHistory ( peerId , showAtMsgId ) ;
2015-07-17 22:17:37 +03:00
}
}
void MainWidget : : clearBotStartToken ( PeerData * peer ) {
2015-09-03 13:48:40 +03:00
if ( peer & & peer - > isUser ( ) & & peer - > asUser ( ) - > botInfo ) {
2015-07-17 22:17:37 +03:00
peer - > asUser ( ) - > botInfo - > startToken = QString ( ) ;
2014-05-30 12:53:19 +04:00
}
2015-07-17 22:17:37 +03:00
}
2015-09-07 18:53:46 +03:00
void MainWidget : : contactsReceived ( ) {
2016-04-13 00:31:28 +03:00
_history - > contactsReceived ( ) ;
2015-09-07 18:53:46 +03:00
}
2015-09-12 22:00:56 +03:00
void MainWidget : : updateAfterDrag ( ) {
2016-04-13 00:31:28 +03:00
if ( _overview ) {
_overview - > updateAfterDrag ( ) ;
2015-09-12 22:00:56 +03:00
} else {
2016-04-13 00:31:28 +03:00
_history - > updateAfterDrag ( ) ;
2015-09-12 22:00:56 +03:00
}
}
2015-09-16 16:04:08 +03:00
void MainWidget : : ctrlEnterSubmitUpdated ( ) {
2016-04-13 00:31:28 +03:00
_history - > updateFieldSubmitSettings ( ) ;
2015-09-16 16:04:08 +03:00
}
2015-12-13 14:36:08 +03:00
void MainWidget : : ui_showPeerHistory ( quint64 peerId , qint32 showAtMsgId , bool back ) {
2015-11-13 18:14:33 +03:00
if ( PeerData * peer = App : : peerLoaded ( peerId ) ) {
if ( peer - > migrateTo ( ) ) {
2016-03-23 16:21:26 +03:00
peer = peer - > migrateTo ( ) ;
peerId = peer - > id ;
2015-11-13 18:14:33 +03:00
if ( showAtMsgId > 0 ) showAtMsgId = - showAtMsgId ;
}
2016-03-23 16:21:26 +03:00
QString restriction = peer - > restrictionReason ( ) ;
if ( ! restriction . isEmpty ( ) ) {
Ui : : showChatsList ( ) ;
Ui : : showLayer ( new InformBox ( restriction ) ) ;
return ;
}
2015-11-13 18:14:33 +03:00
}
2015-07-17 22:17:37 +03:00
if ( ! back & & ( ! peerId | | ( _stack . size ( ) = = 1 & & _stack [ 0 ] - > type ( ) = = HistoryStackItem & & _stack [ 0 ] - > peer - > id = = peerId ) ) ) {
back = true ;
}
2015-09-20 11:55:41 +03:00
PeerData * wasActivePeer = activePeer ( ) ;
2015-12-07 21:09:05 +03:00
Ui : : hideLayer ( ) ;
2015-07-17 22:17:37 +03:00
if ( _hider ) {
_hider - > startHide ( ) ;
2016-04-13 00:31:28 +03:00
_hider = nullptr ;
2015-07-17 22:17:37 +03:00
}
2016-05-19 15:03:51 +03:00
Window : : SectionSlideParams animationParams ;
if ( ! _a_show . animating ( ) & & ( ( _history - > isHidden ( ) & & ( _wideSection | | _overview ) ) | | ( Adaptive : : OneColumn ( ) & & ( _history - > isHidden ( ) | | ! peerId ) ) ) ) {
animationParams = prepareHistoryAnimation ( peerId ) ;
2014-05-30 12:53:19 +04:00
}
2016-04-13 00:31:28 +03:00
if ( _history - > peer ( ) & & _history - > peer ( ) - > id ! = peerId ) clearBotStartToken ( _history - > peer ( ) ) ;
_history - > showHistory ( peerId , showAtMsgId ) ;
2015-07-17 22:17:37 +03:00
2016-04-13 00:31:28 +03:00
bool noPeer = ( ! _history - > peer ( ) | | ! _history - > peer ( ) - > id ) , onlyDialogs = noPeer & & Adaptive : : OneColumn ( ) ;
2016-05-19 15:03:51 +03:00
if ( _wideSection | | _overview ) {
if ( _wideSection ) {
_wideSection - > hide ( ) ;
_wideSection - > deleteLater ( ) ;
_wideSection = nullptr ;
2015-07-17 22:17:37 +03:00
}
2016-04-13 00:31:28 +03:00
if ( _overview ) {
_overview - > hide ( ) ;
_overview - > clear ( ) ;
_overview - > deleteLater ( ) ;
_overview - > rpcClear ( ) ;
_overview = nullptr ;
2015-07-17 22:17:37 +03:00
}
clearBotStartToken ( _peerInStack ) ;
2015-10-14 13:51:37 +02:00
dlgUpdated ( ) ;
2015-07-17 22:17:37 +03:00
_peerInStack = 0 ;
_msgIdInStack = 0 ;
_stack . clear ( ) ;
}
if ( onlyDialogs ) {
2016-04-13 00:31:28 +03:00
_topBar - > hide ( ) ;
_history - > hide ( ) ;
2015-10-17 16:52:26 +02:00
if ( ! _a_show . animating ( ) ) {
2016-05-19 15:03:51 +03:00
if ( ! animationParams . oldContentCache . isNull ( ) ) {
_dialogs - > showAnimated ( back ? Window : : SlideDirection : : FromLeft : Window : : SlideDirection : : FromRight , animationParams ) ;
} else {
_dialogs - > show ( ) ;
2014-08-15 15:19:32 +04:00
}
2014-12-12 19:27:03 +03:00
}
2015-07-17 22:17:37 +03:00
} else {
if ( noPeer ) {
2016-04-13 00:31:28 +03:00
_topBar - > hide ( ) ;
2015-07-17 22:17:37 +03:00
resizeEvent ( 0 ) ;
2015-09-21 23:57:42 +03:00
} else if ( wasActivePeer ! = activePeer ( ) ) {
if ( activePeer ( ) - > isChannel ( ) ) {
activePeer ( ) - > asChannel ( ) - > ptsWaitingForShortPoll ( WaitForChannelGetDifference ) ;
}
_viewsIncremented . remove ( activePeer ( ) ) ;
2015-07-17 22:17:37 +03:00
}
2016-04-13 00:31:28 +03:00
if ( Adaptive : : OneColumn ( ) & & ! _dialogs - > isHidden ( ) ) _dialogs - > hide ( ) ;
2015-10-17 16:52:26 +02:00
if ( ! _a_show . animating ( ) ) {
2016-05-19 15:03:51 +03:00
if ( ! animationParams . oldContentCache . isNull ( ) ) {
_history - > showAnimated ( back ? Window : : SlideDirection : : FromLeft : Window : : SlideDirection : : FromRight , animationParams ) ;
} else {
_history - > show ( ) ;
if ( App : : wnd ( ) ) {
QTimer : : singleShot ( 0 , App : : wnd ( ) , SLOT ( setInnerFocus ( ) ) ) ;
}
2014-05-30 12:53:19 +04:00
}
}
}
2015-09-20 11:55:41 +03:00
//if (wasActivePeer && wasActivePeer->isChannel() && activePeer() != wasActivePeer) {
2015-09-20 12:54:22 +03:00
// wasActivePeer->asChannel()->ptsWaitingForShortPoll(false);
2015-09-20 11:55:41 +03:00
//}
2015-07-17 22:17:37 +03:00
2016-04-13 00:31:28 +03:00
if ( ! _dialogs - > isHidden ( ) ) {
2015-12-07 13:06:59 +03:00
if ( ! back ) {
2016-04-13 00:31:28 +03:00
_dialogs - > scrollToPeer ( peerId , showAtMsgId ) ;
2015-12-07 13:06:59 +03:00
}
2016-04-13 00:31:28 +03:00
_dialogs - > update ( ) ;
2014-12-12 19:27:03 +03:00
}
App : : wnd ( ) - > getTitle ( ) - > updateBackButton ( ) ;
2014-05-30 12:53:19 +04:00
}
2016-03-29 20:17:00 +03:00
PeerData * MainWidget : : ui_getPeerForMouseAction ( ) {
2016-05-19 15:03:51 +03:00
if ( _wideSection ) {
//return _wideSection->ui_getPeerForMouseAction(); TODO
2016-03-29 20:17:00 +03:00
}
2016-04-13 00:31:28 +03:00
return _history - > ui_getPeerForMouseAction ( ) ;
2016-03-29 20:17:00 +03:00
}
2014-08-22 11:41:39 +04:00
void MainWidget : : peerBefore ( const PeerData * inPeer , MsgId inMsg , PeerData * & outPeer , MsgId & outMsg ) {
if ( selectingPeer ( ) ) {
outPeer = 0 ;
outMsg = 0 ;
return ;
}
2016-04-13 00:31:28 +03:00
_dialogs - > peerBefore ( inPeer , inMsg , outPeer , outMsg ) ;
2014-05-30 12:53:19 +04:00
}
2014-08-22 11:41:39 +04:00
void MainWidget : : peerAfter ( const PeerData * inPeer , MsgId inMsg , PeerData * & outPeer , MsgId & outMsg ) {
if ( selectingPeer ( ) ) {
outPeer = 0 ;
outMsg = 0 ;
return ;
}
2016-04-13 00:31:28 +03:00
_dialogs - > peerAfter ( inPeer , inMsg , outPeer , outMsg ) ;
2014-05-30 12:53:19 +04:00
}
2014-12-15 18:55:45 +03:00
PeerData * MainWidget : : historyPeer ( ) {
2016-04-13 00:31:28 +03:00
return _history - > peer ( ) ;
2014-12-15 18:55:45 +03:00
}
2014-05-30 12:53:19 +04:00
PeerData * MainWidget : : peer ( ) {
2016-04-13 00:31:28 +03:00
return _overview ? _overview - > peer ( ) : _history - > peer ( ) ;
2014-05-30 12:53:19 +04:00
}
PeerData * MainWidget : : activePeer ( ) {
2016-04-13 00:31:28 +03:00
return _history - > peer ( ) ? _history - > peer ( ) : _peerInStack ;
2014-05-30 12:53:19 +04:00
}
2014-07-04 15:12:54 +04:00
MsgId MainWidget : : activeMsgId ( ) {
2016-04-13 00:31:28 +03:00
return _history - > peer ( ) ? _history - > msgId ( ) : _msgIdInStack ;
2014-07-04 15:12:54 +04:00
}
2015-07-03 11:47:16 +03:00
PeerData * MainWidget : : overviewPeer ( ) {
2016-04-13 00:31:28 +03:00
return _overview ? _overview - > peer ( ) : 0 ;
2015-07-03 11:47:16 +03:00
}
2014-08-21 16:18:56 +04:00
bool MainWidget : : mediaTypeSwitch ( ) {
2016-04-13 00:31:28 +03:00
if ( ! _overview ) return false ;
2014-08-21 16:18:56 +04:00
for ( int32 i = 0 ; i < OverviewCount ; + + i ) {
if ( ! ( _mediaTypeMask & ~ ( 1 < < i ) ) ) {
return false ;
}
}
return true ;
}
void MainWidget : : showMediaOverview ( PeerData * peer , MediaOverviewType type , bool back , int32 lastScrollTop ) {
2015-11-13 18:14:33 +03:00
if ( peer - > migrateTo ( ) ) {
peer = peer - > migrateTo ( ) ;
}
2014-08-15 15:19:32 +04:00
App : : wnd ( ) - > hideSettings ( ) ;
2016-04-13 00:31:28 +03:00
if ( _overview & & _overview - > peer ( ) = = peer ) {
if ( _overview - > type ( ) ! = type ) {
_overview - > switchType ( type ) ;
2016-02-12 19:35:06 +03:00
} else if ( type = = OverviewMusicFiles ) { // hack for player
2015-07-03 11:47:16 +03:00
showBackFromStack ( ) ;
2014-08-15 15:19:32 +04:00
}
return ;
}
2016-05-19 15:03:51 +03:00
Window : : SectionSlideParams animationParams ;
if ( ! _a_show . animating ( ) & & ( Adaptive : : OneColumn ( ) | | _wideSection | | _overview | | _history - > peer ( ) ) ) {
animationParams = prepareOverviewAnimation ( ) ;
2015-07-03 11:47:16 +03:00
}
2014-08-15 15:19:32 +04:00
if ( ! back ) {
2016-04-13 00:31:28 +03:00
if ( _overview ) {
_stack . push_back ( new StackItemOverview ( _overview - > peer ( ) , _overview - > type ( ) , _overview - > lastWidth ( ) , _overview - > lastScrollTop ( ) ) ) ;
2016-05-19 15:03:51 +03:00
} else if ( _wideSection ) {
_stack . push_back ( new StackItemSection ( _wideSection - > createMemento ( ) ) ) ;
2016-04-13 00:31:28 +03:00
} else if ( _history - > peer ( ) ) {
2015-10-14 13:51:37 +02:00
dlgUpdated ( ) ;
2016-04-13 00:31:28 +03:00
_peerInStack = _history - > peer ( ) ;
_msgIdInStack = _history - > msgId ( ) ;
2015-10-14 13:51:37 +02:00
dlgUpdated ( ) ;
2016-04-13 00:31:28 +03:00
_stack . push_back ( new StackItemHistory ( _peerInStack , _msgIdInStack , _history - > replyReturns ( ) ) ) ;
2014-08-15 15:19:32 +04:00
}
}
2016-04-13 00:31:28 +03:00
if ( _overview ) {
_overview - > hide ( ) ;
_overview - > clear ( ) ;
_overview - > deleteLater ( ) ;
_overview - > rpcClear ( ) ;
2014-08-15 15:19:32 +04:00
}
2016-05-19 15:03:51 +03:00
if ( _wideSection ) {
_wideSection - > hide ( ) ;
_wideSection - > deleteLater ( ) ;
_wideSection = nullptr ;
2014-08-15 15:19:32 +04:00
}
2016-04-13 00:31:28 +03:00
_overview = new OverviewWidget ( this , peer , type ) ;
2014-08-21 16:18:56 +04:00
_mediaTypeMask = 0 ;
2016-04-13 00:31:28 +03:00
_topBar - > show ( ) ;
resizeEvent ( nullptr ) ;
2015-07-03 11:47:16 +03:00
mediaOverviewUpdated ( peer , type ) ;
2016-05-19 15:03:51 +03:00
_overview - > setLastScrollTop ( lastScrollTop ) ;
if ( ! animationParams . oldContentCache . isNull ( ) ) {
_overview - > showAnimated ( back ? Window : : SlideDirection : : FromLeft : Window : : SlideDirection : : FromRight , animationParams ) ;
2015-07-03 11:47:16 +03:00
} else {
2016-04-13 00:31:28 +03:00
_overview - > fastShow ( ) ;
2015-07-03 11:47:16 +03:00
}
2016-04-13 00:31:28 +03:00
_history - > animStop ( ) ;
if ( back ) clearBotStartToken ( _history - > peer ( ) ) ;
_history - > showHistory ( 0 , 0 ) ;
_history - > hide ( ) ;
if ( Adaptive : : OneColumn ( ) ) _dialogs - > hide ( ) ;
2015-07-17 22:17:37 +03:00
orderWidgets ( ) ;
2014-12-12 19:27:03 +03:00
App : : wnd ( ) - > getTitle ( ) - > updateBackButton ( ) ;
2014-08-15 15:19:32 +04:00
}
2016-05-19 15:03:51 +03:00
void MainWidget : : showWideSection ( Window : : SectionMemento & memento ) {
App : : wnd ( ) - > hideSettings ( ) ;
if ( _wideSection & & _wideSection - > showInternal ( & memento ) ) {
return ;
2015-11-13 18:14:33 +03:00
}
2016-05-19 15:03:51 +03:00
if ( _overview ) {
_stack . push_back ( new StackItemOverview ( _overview - > peer ( ) , _overview - > type ( ) , _overview - > lastWidth ( ) , _overview - > lastScrollTop ( ) ) ) ;
} else if ( _wideSection ) {
_stack . push_back ( new StackItemSection ( _wideSection - > createMemento ( ) ) ) ;
} else if ( _history - > peer ( ) ) {
dlgUpdated ( ) ;
_peerInStack = _history - > peer ( ) ;
_msgIdInStack = _history - > msgId ( ) ;
dlgUpdated ( ) ;
_stack . push_back ( new StackItemHistory ( _peerInStack , _msgIdInStack , _history - > replyReturns ( ) ) ) ;
}
showWideSectionAnimated ( & memento , false ) ;
}
2014-08-11 13:03:45 +04:00
2016-05-19 15:03:51 +03:00
Window : : SectionSlideParams MainWidget : : prepareShowAnimation ( bool willHaveTopBarShadow ) {
Window : : SectionSlideParams result ;
result . withTopBarShadow = willHaveTopBarShadow ;
if ( selectingPeer ( ) & & Adaptive : : OneColumn ( ) ) {
result . withTopBarShadow = false ;
} else if ( _wideSection ) {
if ( ! _wideSection - > hasTopBarShadow ( ) ) {
result . withTopBarShadow = false ;
}
} else if ( ! _overview & & ! _history - > peer ( ) ) {
result . withTopBarShadow = false ;
2016-05-12 19:05:20 +03:00
}
2016-05-19 15:03:51 +03:00
if ( selectingPeer ( ) & & Adaptive : : OneColumn ( ) ) {
result . oldContentCache = myGrab ( this , QRect ( 0 , _playerHeight , _dialogsWidth , height ( ) - _playerHeight ) ) ;
} else if ( _wideSection ) {
result . oldContentCache = _wideSection - > grabForShowAnimation ( result ) ;
} else {
if ( result . withTopBarShadow ) {
if ( _overview ) _overview - > grapWithoutTopBarShadow ( ) ;
_history - > grapWithoutTopBarShadow ( ) ;
} else {
if ( _overview ) _overview - > grabStart ( ) ;
_history - > grabStart ( ) ;
}
if ( Adaptive : : OneColumn ( ) ) {
result . oldContentCache = myGrab ( this , QRect ( 0 , _playerHeight , _dialogsWidth , height ( ) - _playerHeight ) ) ;
} else {
_sideShadow . hide ( ) ;
result . oldContentCache = myGrab ( this , QRect ( _dialogsWidth , _playerHeight , width ( ) - _dialogsWidth , height ( ) - _playerHeight ) ) ;
_sideShadow . show ( ) ;
2014-05-30 12:53:19 +04:00
}
2016-05-19 15:03:51 +03:00
if ( _overview ) _overview - > grabFinish ( ) ;
_history - > grabFinish ( ) ;
2014-05-30 12:53:19 +04:00
}
2016-05-19 15:03:51 +03:00
return result ;
}
Window : : SectionSlideParams MainWidget : : prepareWideSectionAnimation ( Window : : SectionWidget * section ) {
return prepareShowAnimation ( section - > hasTopBarShadow ( ) ) ;
}
Window : : SectionSlideParams MainWidget : : prepareHistoryAnimation ( PeerId historyPeerId ) {
return prepareShowAnimation ( historyPeerId ! = 0 ) ;
}
Window : : SectionSlideParams MainWidget : : prepareOverviewAnimation ( ) {
return prepareShowAnimation ( true ) ;
}
Window : : SectionSlideParams MainWidget : : prepareDialogsAnimation ( ) {
return prepareShowAnimation ( false ) ;
}
void MainWidget : : showWideSectionAnimated ( Window : : SectionMemento * memento , bool back ) {
QPixmap animCache ;
auto newWideGeometry = QRect ( _history - > x ( ) , _playerHeight , _history - > width ( ) , height ( ) - _playerHeight ) ;
auto newWideSection = memento - > createWidget ( this , newWideGeometry ) ;
Window : : SectionSlideParams animationParams = prepareWideSectionAnimation ( newWideSection ) ;
2016-04-13 00:31:28 +03:00
if ( _overview ) {
_overview - > hide ( ) ;
_overview - > clear ( ) ;
_overview - > deleteLater ( ) ;
_overview - > rpcClear ( ) ;
_overview = nullptr ;
2014-08-15 15:19:32 +04:00
}
2016-05-19 15:03:51 +03:00
if ( _wideSection ) {
_wideSection - > hide ( ) ;
_wideSection - > deleteLater ( ) ;
_wideSection = nullptr ;
2014-08-01 15:09:46 +04:00
}
2016-05-19 15:03:51 +03:00
_wideSection = newWideSection ;
2016-05-12 19:05:20 +03:00
_topBar - > hide ( ) ;
2014-05-30 12:53:19 +04:00
resizeEvent ( 0 ) ;
2016-05-19 15:03:51 +03:00
auto direction = back ? Window : : SlideDirection : : FromLeft : Window : : SlideDirection : : FromRight ;
_wideSection - > showAnimated ( direction , animationParams ) ;
2016-04-13 00:31:28 +03:00
_history - > animStop ( ) ;
_history - > showHistory ( 0 , 0 ) ;
_history - > hide ( ) ;
if ( Adaptive : : OneColumn ( ) ) _dialogs - > hide ( ) ;
2015-07-17 22:17:37 +03:00
orderWidgets ( ) ;
2014-12-12 19:27:03 +03:00
App : : wnd ( ) - > getTitle ( ) - > updateBackButton ( ) ;
2014-05-30 12:53:19 +04:00
}
2014-08-15 15:19:32 +04:00
void MainWidget : : showBackFromStack ( ) {
2015-07-03 11:47:16 +03:00
if ( selectingPeer ( ) ) return ;
if ( _stack . isEmpty ( ) ) {
2015-12-13 14:36:08 +03:00
Ui : : showChatsList ( ) ;
2015-09-16 16:04:08 +03:00
if ( App : : wnd ( ) ) QTimer : : singleShot ( 0 , App : : wnd ( ) , SLOT ( setInnerFocus ( ) ) ) ;
2015-07-03 11:47:16 +03:00
return ;
}
2014-08-15 15:19:32 +04:00
StackItem * item = _stack . back ( ) ;
_stack . pop_back ( ) ;
2016-05-19 15:03:51 +03:00
if ( auto currentHistoryPeer = _history - > peer ( ) ) {
clearBotStartToken ( currentHistoryPeer ) ;
}
2014-08-15 15:19:32 +04:00
if ( item - > type ( ) = = HistoryStackItem ) {
2015-10-14 13:51:37 +02:00
dlgUpdated ( ) ;
2015-07-17 22:17:37 +03:00
_peerInStack = 0 ;
_msgIdInStack = 0 ;
for ( int32 i = _stack . size ( ) ; i > 0 ; ) {
if ( _stack . at ( - - i ) - > type ( ) = = HistoryStackItem ) {
_peerInStack = static_cast < StackItemHistory * > ( _stack . at ( i ) ) - > peer ;
_msgIdInStack = static_cast < StackItemHistory * > ( _stack . at ( i ) ) - > msgId ;
2015-10-14 13:51:37 +02:00
dlgUpdated ( ) ;
2015-07-17 22:17:37 +03:00
break ;
}
}
2014-08-15 15:19:32 +04:00
StackItemHistory * histItem = static_cast < StackItemHistory * > ( item ) ;
2015-12-13 14:36:08 +03:00
Ui : : showPeerHistory ( histItem - > peer - > id , App : : main ( ) - > activeMsgId ( ) , true ) ;
2016-04-13 00:31:28 +03:00
_history - > setReplyReturns ( histItem - > peer - > id , histItem - > replyReturns ) ;
2016-05-19 15:03:51 +03:00
} else if ( item - > type ( ) = = SectionStackItem ) {
StackItemSection * sectionItem = static_cast < StackItemSection * > ( item ) ;
showWideSectionAnimated ( sectionItem - > memento ( ) , true ) ;
2014-08-15 15:19:32 +04:00
} else if ( item - > type ( ) = = OverviewStackItem ) {
StackItemOverview * overItem = static_cast < StackItemOverview * > ( item ) ;
showMediaOverview ( overItem - > peer , overItem - > mediaType , true , overItem - > lastScrollTop ) ;
2014-05-30 12:53:19 +04:00
}
2014-08-15 15:19:32 +04:00
delete item ;
2014-05-30 12:53:19 +04:00
}
2015-07-17 22:17:37 +03:00
void MainWidget : : orderWidgets ( ) {
2016-04-13 00:31:28 +03:00
_topBar - > raise ( ) ;
_player - > raise ( ) ;
_dialogs - > raise ( ) ;
_mediaType - > raise ( ) ;
2016-05-14 19:57:06 +03:00
_sideShadow . raise ( ) ;
2015-07-17 22:17:37 +03:00
if ( _hider ) _hider - > raise ( ) ;
}
2014-05-30 12:53:19 +04:00
QRect MainWidget : : historyRect ( ) const {
2016-04-13 00:31:28 +03:00
QRect r ( _history - > historyRect ( ) ) ;
r . moveLeft ( r . left ( ) + _history - > x ( ) ) ;
r . moveTop ( r . top ( ) + _history - > y ( ) ) ;
2014-05-30 12:53:19 +04:00
return r ;
}
2016-05-19 15:03:51 +03:00
QPixmap MainWidget : : grabForShowAnimation ( const Window : : SectionSlideParams & params ) {
_topBar - > stopAnim ( ) ;
QPixmap result ;
if ( Adaptive : : OneColumn ( ) ) {
result = myGrab ( this , QRect ( 0 , _playerHeight , _dialogsWidth , height ( ) - _playerHeight ) ) ;
} else {
_sideShadow . hide ( ) ;
result = myGrab ( this , QRect ( _dialogsWidth , _playerHeight , width ( ) - _dialogsWidth , height ( ) - _playerHeight ) ) ;
_sideShadow . show ( ) ;
}
return result ;
}
2016-04-11 14:59:01 +04:00
void MainWidget : : dlgUpdated ( ) {
if ( _peerInStack ) {
2016-04-13 00:31:28 +03:00
_dialogs - > dlgUpdated ( App : : history ( _peerInStack - > id ) , _msgIdInStack ) ;
2015-10-14 13:51:37 +02:00
}
2014-05-30 12:53:19 +04:00
}
2016-04-11 14:59:01 +04:00
void MainWidget : : dlgUpdated ( Dialogs : : Mode list , Dialogs : : Row * row ) {
if ( row ) {
2016-04-13 00:31:28 +03:00
_dialogs - > dlgUpdated ( list , row ) ;
2016-04-11 14:59:01 +04:00
}
}
2015-10-03 13:09:09 +03:00
void MainWidget : : dlgUpdated ( History * row , MsgId msgId ) {
if ( ! row ) return ;
2015-11-13 18:14:33 +03:00
if ( msgId < 0 & & - msgId < ServerMaxMsgId & & row - > peer - > migrateFrom ( ) ) {
2016-04-13 00:31:28 +03:00
_dialogs - > dlgUpdated ( App : : history ( row - > peer - > migrateFrom ( ) - > id ) , - msgId ) ;
2015-11-13 18:14:33 +03:00
} else {
2016-04-13 00:31:28 +03:00
_dialogs - > dlgUpdated ( row , msgId ) ;
2015-11-13 18:14:33 +03:00
}
2014-05-30 12:53:19 +04:00
}
void MainWidget : : windowShown ( ) {
2016-04-13 00:31:28 +03:00
_history - > windowShown ( ) ;
2014-05-30 12:53:19 +04:00
}
2015-08-30 17:57:21 +03:00
void MainWidget : : sentUpdatesReceived ( uint64 randomId , const MTPUpdates & result ) {
2015-09-21 23:57:42 +03:00
feedUpdates ( result , randomId ) ;
2016-05-25 15:09:05 +03:00
Notify : : peerUpdatedSendDelayed ( ) ;
2014-05-30 12:53:19 +04:00
}
2016-03-23 19:50:40 +03:00
bool MainWidget : : deleteChannelFailed ( const RPCError & error ) {
2016-04-08 14:44:35 +04:00
if ( MTP : : isDefaultHandledError ( error ) ) return false ;
2016-03-23 19:50:40 +03:00
//if (error.type() == qstr("CHANNEL_TOO_LARGE")) {
// Ui::showLayer(new InformBox(lang(lng_cant_delete_channel)));
//}
return true ;
}
2015-09-23 20:43:08 +03:00
void MainWidget : : inviteToChannelDone ( ChannelData * channel , const MTPUpdates & updates ) {
sentUpdatesReceived ( updates ) ;
2015-09-25 10:47:32 +03:00
QTimer : : singleShot ( ReloadChannelMembersTimeout , this , SLOT ( onActiveChannelUpdateFull ( ) ) ) ;
}
void MainWidget : : onActiveChannelUpdateFull ( ) {
if ( activePeer ( ) & & activePeer ( ) - > isChannel ( ) ) {
activePeer ( ) - > asChannel ( ) - > updateFull ( true ) ;
}
2015-09-23 20:43:08 +03:00
}
2014-05-30 12:53:19 +04:00
void MainWidget : : historyToDown ( History * hist ) {
2016-04-13 00:31:28 +03:00
_history - > historyToDown ( hist ) ;
2014-05-30 12:53:19 +04:00
}
void MainWidget : : dialogsToUp ( ) {
2016-04-13 00:31:28 +03:00
_dialogs - > dialogsToUp ( ) ;
2014-05-30 12:53:19 +04:00
}
2015-03-19 12:18:19 +03:00
void MainWidget : : newUnreadMsg ( History * hist , HistoryItem * item ) {
2016-04-13 00:31:28 +03:00
_history - > newUnreadMsg ( hist , item ) ;
2014-05-30 12:53:19 +04:00
}
void MainWidget : : historyWasRead ( ) {
2016-04-13 00:31:28 +03:00
_history - > historyWasRead ( false ) ;
2014-05-30 12:53:19 +04:00
}
2015-06-17 22:43:03 +03:00
void MainWidget : : historyCleared ( History * hist ) {
2016-04-13 00:31:28 +03:00
_history - > historyCleared ( hist ) ;
2015-06-17 22:43:03 +03:00
}
2014-05-30 12:53:19 +04:00
void MainWidget : : animShow ( const QPixmap & bgAnimCache , bool back ) {
2015-10-15 13:51:10 +02:00
if ( App : : app ( ) ) App : : app ( ) - > mtpPause ( ) ;
2015-10-15 12:18:24 +02:00
2015-10-17 16:52:26 +02:00
( back ? _cacheOver : _cacheUnder ) = bgAnimCache ;
_a_show . stop ( ) ;
2014-05-30 12:53:19 +04:00
showAll ( ) ;
2015-10-17 16:52:26 +02:00
( back ? _cacheUnder : _cacheOver ) = myGrab ( this ) ;
hideAll ( ) ;
2014-05-30 12:53:19 +04:00
2016-05-14 19:57:06 +03:00
a_coordUnder = back ? anim : : ivalue ( - st : : slideShift , 0 ) : anim : : ivalue ( 0 , - st : : slideShift ) ;
2015-10-17 16:52:26 +02:00
a_coordOver = back ? anim : : ivalue ( 0 , width ( ) ) : anim : : ivalue ( width ( ) , 0 ) ;
a_shadow = back ? anim : : fvalue ( 1 , 0 ) : anim : : fvalue ( 0 , 1 ) ;
_a_show . start ( ) ;
2014-05-30 12:53:19 +04:00
show ( ) ;
}
2015-12-08 15:33:37 +03:00
void MainWidget : : step_show ( float64 ms , bool timer ) {
2015-10-17 16:52:26 +02:00
float64 dt = ms / st : : slideDuration ;
if ( dt > = 1 ) {
_a_show . stop ( ) ;
a_coordUnder . finish ( ) ;
a_coordOver . finish ( ) ;
a_shadow . finish ( ) ;
2014-05-30 12:53:19 +04:00
2015-10-17 16:52:26 +02:00
_cacheUnder = _cacheOver = QPixmap ( ) ;
2014-05-30 12:53:19 +04:00
showAll ( ) ;
activate ( ) ;
2015-10-15 12:18:24 +02:00
if ( App : : app ( ) ) App : : app ( ) - > mtpUnpause ( ) ;
2014-05-30 12:53:19 +04:00
} else {
2015-10-17 16:52:26 +02:00
a_coordUnder . update ( dt , st : : slideFunction ) ;
a_coordOver . update ( dt , st : : slideFunction ) ;
a_shadow . update ( dt , st : : slideFunction ) ;
2014-05-30 12:53:19 +04:00
}
2015-12-08 15:33:37 +03:00
if ( timer ) update ( ) ;
2014-05-30 12:53:19 +04:00
}
2015-10-17 16:52:26 +02:00
void MainWidget : : animStop_show ( ) {
_a_show . stop ( ) ;
}
2014-05-30 12:53:19 +04:00
void MainWidget : : paintEvent ( QPaintEvent * e ) {
2015-02-03 18:02:46 +03:00
if ( _background ) checkChatBackground ( ) ;
2015-10-17 16:52:26 +02:00
Painter p ( this ) ;
if ( _a_show . animating ( ) ) {
if ( a_coordOver . current ( ) > 0 ) {
2015-10-19 01:01:18 +02:00
p . drawPixmap ( QRect ( 0 , 0 , a_coordOver . current ( ) , height ( ) ) , _cacheUnder , QRect ( - a_coordUnder . current ( ) * cRetinaFactor ( ) , 0 , a_coordOver . current ( ) * cRetinaFactor ( ) , height ( ) * cRetinaFactor ( ) ) ) ;
2015-10-17 16:52:26 +02:00
p . setOpacity ( a_shadow . current ( ) * st : : slideFadeOut ) ;
p . fillRect ( 0 , 0 , a_coordOver . current ( ) , height ( ) , st : : black - > b ) ;
p . setOpacity ( 1 ) ;
}
p . drawPixmap ( a_coordOver . current ( ) , 0 , _cacheOver ) ;
p . setOpacity ( a_shadow . current ( ) ) ;
2016-04-21 20:57:29 +03:00
p . drawPixmap ( QRect ( a_coordOver . current ( ) - st : : slideShadow . pxWidth ( ) , 0 , st : : slideShadow . pxWidth ( ) , height ( ) ) , App : : sprite ( ) , st : : slideShadow . rect ( ) ) ;
2014-05-30 12:53:19 +04:00
}
}
void MainWidget : : hideAll ( ) {
2016-04-13 00:31:28 +03:00
_dialogs - > hide ( ) ;
_history - > hide ( ) ;
2016-05-19 15:03:51 +03:00
if ( _wideSection ) {
_wideSection - > hide ( ) ;
2014-05-30 12:53:19 +04:00
}
2016-04-13 00:31:28 +03:00
if ( _overview ) {
_overview - > hide ( ) ;
2014-08-15 15:19:32 +04:00
}
2016-05-19 15:03:51 +03:00
_sideShadow . hide ( ) ;
2016-04-13 00:31:28 +03:00
_topBar - > hide ( ) ;
_mediaType - > hide ( ) ;
2016-04-14 19:08:36 +03:00
if ( _player - > isOpened ( ) & & ! _player - > isHidden ( ) ) {
_player - > hidePlayer ( ) ;
_playerHeight = 0 ;
}
2014-05-30 12:53:19 +04:00
}
void MainWidget : : showAll ( ) {
2015-04-02 13:33:19 +03:00
if ( cPasswordRecovered ( ) ) {
cSetPasswordRecovered ( false ) ;
2015-12-07 21:09:05 +03:00
Ui : : showLayer ( new InformBox ( lang ( lng_signin_password_removed ) ) ) ;
2015-04-02 13:33:19 +03:00
}
2016-05-19 15:03:51 +03:00
_sideShadow . show ( ) ;
2016-02-08 17:54:55 +03:00
if ( Adaptive : : OneColumn ( ) ) {
2015-07-17 22:17:37 +03:00
if ( _hider ) {
_hider - > hide ( ) ;
if ( ! _forwardConfirm & & _hider - > wasOffered ( ) ) {
2015-10-03 13:09:09 +03:00
_forwardConfirm = new ConfirmBox ( _hider - > offeredText ( ) , lang ( lng_forward_send ) ) ;
2015-07-17 22:17:37 +03:00
connect ( _forwardConfirm , SIGNAL ( confirmed ( ) ) , _hider , SLOT ( forward ( ) ) ) ;
2014-12-12 19:27:03 +03:00
connect ( _forwardConfirm , SIGNAL ( cancelled ( ) ) , this , SLOT ( onForwardCancel ( ) ) ) ;
2015-12-07 21:09:05 +03:00
Ui : : showLayer ( _forwardConfirm , ForceFastShowLayer ) ;
2014-12-12 19:27:03 +03:00
}
}
if ( selectingPeer ( ) ) {
2016-04-13 00:31:28 +03:00
_dialogs - > show ( ) ;
_history - > hide ( ) ;
if ( _overview ) _overview - > hide ( ) ;
2016-05-19 15:03:51 +03:00
if ( _wideSection ) _wideSection - > hide ( ) ;
2016-04-13 00:31:28 +03:00
_topBar - > hide ( ) ;
} else if ( _overview ) {
_overview - > show ( ) ;
2016-05-19 15:03:51 +03:00
} else if ( _wideSection ) {
_wideSection - > show ( ) ;
2016-04-13 00:31:28 +03:00
} else if ( _history - > peer ( ) ) {
_history - > show ( ) ;
_history - > resizeEvent ( 0 ) ;
2014-12-12 19:27:03 +03:00
} else {
2016-04-13 00:31:28 +03:00
_dialogs - > show ( ) ;
_history - > hide ( ) ;
2014-12-12 19:27:03 +03:00
}
2016-05-19 15:03:51 +03:00
if ( _wideSection ) {
2016-05-12 19:05:20 +03:00
_topBar - > hide ( ) ;
2016-05-19 15:38:09 +03:00
_dialogs - > hide ( ) ;
2016-05-12 19:05:20 +03:00
} else if ( ! selectingPeer ( ) & & ( _overview | | _history - > peer ( ) ) ) {
2016-04-13 00:31:28 +03:00
_topBar - > show ( ) ;
_dialogs - > hide ( ) ;
2014-12-12 19:27:03 +03:00
}
2016-02-08 17:54:55 +03:00
} else {
if ( _hider ) {
_hider - > show ( ) ;
if ( _forwardConfirm ) {
Ui : : hideLayer ( true ) ;
_forwardConfirm = 0 ;
}
}
2016-04-13 00:31:28 +03:00
_dialogs - > show ( ) ;
if ( _overview ) {
_overview - > show ( ) ;
2016-05-19 15:03:51 +03:00
} else if ( _wideSection ) {
_wideSection - > show ( ) ;
2016-02-08 17:54:55 +03:00
} else {
2016-04-13 00:31:28 +03:00
_history - > show ( ) ;
_history - > resizeEvent ( 0 ) ;
2016-02-08 17:54:55 +03:00
}
2016-05-19 15:03:51 +03:00
if ( _wideSection ) {
2016-05-12 19:05:20 +03:00
_topBar - > hide ( ) ;
} else if ( _overview | | _history - > peer ( ) ) {
2016-04-13 00:31:28 +03:00
_topBar - > show ( ) ;
2016-02-08 17:54:55 +03:00
}
2014-05-30 12:53:19 +04:00
}
2016-04-14 19:08:36 +03:00
if ( _player - > isOpened ( ) & & _player - > isHidden ( ) ) {
_player - > showPlayer ( ) ;
_playerHeight = _player - > height ( ) ;
2015-10-17 10:31:48 +02:00
}
2015-12-06 19:28:07 +03:00
resizeEvent ( 0 ) ;
2015-10-17 10:31:48 +02:00
2014-05-30 12:53:19 +04:00
App : : wnd ( ) - > checkHistoryActivation ( ) ;
}
void MainWidget : : resizeEvent ( QResizeEvent * e ) {
2016-04-13 00:31:28 +03:00
int32 tbh = _topBar - > isHidden ( ) ? 0 : st : : topBarHeight ;
2016-02-08 17:54:55 +03:00
if ( Adaptive : : OneColumn ( ) ) {
_dialogsWidth = width ( ) ;
2016-04-13 00:31:28 +03:00
_player - > setGeometry ( 0 , 0 , _dialogsWidth , _player - > height ( ) ) ;
_dialogs - > setGeometry ( 0 , _playerHeight , _dialogsWidth , height ( ) - _playerHeight ) ;
_topBar - > setGeometry ( 0 , _playerHeight , _dialogsWidth , st : : topBarHeight ) ;
_history - > setGeometry ( 0 , _playerHeight + tbh , _dialogsWidth , height ( ) - _playerHeight - tbh ) ;
2016-02-08 17:54:55 +03:00
if ( _hider ) _hider - > setGeometry ( 0 , 0 , _dialogsWidth , height ( ) ) ;
} else {
2016-02-09 19:05:08 +03:00
_dialogsWidth = chatsListWidth ( width ( ) ) ;
2016-04-13 00:31:28 +03:00
_dialogs - > resize ( _dialogsWidth , height ( ) ) ;
_dialogs - > moveToLeft ( 0 , 0 ) ;
2016-05-14 19:57:06 +03:00
_sideShadow . resize ( st : : lineWidth , height ( ) ) ;
_sideShadow . moveToLeft ( _dialogsWidth , 0 ) ;
2016-04-13 00:31:28 +03:00
_player - > resize ( width ( ) - _dialogsWidth , _player - > height ( ) ) ;
_player - > moveToLeft ( _dialogsWidth , 0 ) ;
_topBar - > resize ( width ( ) - _dialogsWidth , st : : topBarHeight ) ;
_topBar - > moveToLeft ( _dialogsWidth , _playerHeight ) ;
_history - > resize ( width ( ) - _dialogsWidth , height ( ) - _playerHeight - tbh ) ;
_history - > moveToLeft ( _dialogsWidth , _playerHeight + tbh ) ;
2015-10-17 10:31:48 +02:00
if ( _hider ) {
_hider - > resize ( width ( ) - _dialogsWidth , height ( ) ) ;
_hider - > moveToLeft ( _dialogsWidth , 0 ) ;
}
2014-12-12 19:27:03 +03:00
}
2016-04-13 00:31:28 +03:00
_mediaType - > moveToLeft ( width ( ) - _mediaType - > width ( ) , _playerHeight + st : : topBarHeight ) ;
2016-05-19 15:03:51 +03:00
if ( _wideSection ) {
QRect wideSectionGeometry ( _history - > x ( ) , _playerHeight , _history - > width ( ) , height ( ) - _playerHeight ) ;
_wideSection - > setGeometryWithTopMoved ( wideSectionGeometry , _contentScrollAddToY ) ;
2016-05-12 19:05:20 +03:00
}
2016-04-13 00:31:28 +03:00
if ( _overview ) _overview - > setGeometry ( _history - > geometry ( ) ) ;
2015-07-03 11:47:16 +03:00
_contentScrollAddToY = 0 ;
}
2016-04-08 13:20:10 +04:00
int MainWidget : : contentScrollAddToY ( ) const {
2015-07-03 11:47:16 +03:00
return _contentScrollAddToY ;
2014-05-30 12:53:19 +04:00
}
void MainWidget : : keyPressEvent ( QKeyEvent * e ) {
}
2016-02-08 17:54:55 +03:00
void MainWidget : : updateAdaptiveLayout ( ) {
2014-12-12 19:27:03 +03:00
showAll ( ) ;
2016-05-14 19:57:06 +03:00
_sideShadow . setVisible ( ! Adaptive : : OneColumn ( ) ) ;
2016-05-19 15:03:51 +03:00
if ( _wideSection ) {
_wideSection - > updateAdaptiveLayout ( ) ;
}
2016-04-13 00:31:28 +03:00
_topBar - > updateAdaptiveLayout ( ) ;
_history - > updateAdaptiveLayout ( ) ;
2014-12-12 19:27:03 +03:00
}
bool MainWidget : : needBackButton ( ) {
2016-05-19 15:03:51 +03:00
return _overview | | _wideSection | | _history - > peer ( ) ;
2014-12-12 19:27:03 +03:00
}
2016-04-21 20:57:29 +03:00
void MainWidget : : paintTopBar ( Painter & p , float64 over , int32 decreaseWidth ) {
2016-05-19 15:03:51 +03:00
if ( _overview ) {
2016-04-13 00:31:28 +03:00
_overview - > paintTopBar ( p , over , decreaseWidth ) ;
2016-05-19 15:03:51 +03:00
} else if ( ! _wideSection ) {
2016-04-13 00:31:28 +03:00
_history - > paintTopBar ( p , over , decreaseWidth ) ;
2014-05-30 12:53:19 +04:00
}
}
2014-08-21 16:18:56 +04:00
void MainWidget : : onPhotosSelect ( ) {
2016-04-13 00:31:28 +03:00
if ( _overview ) _overview - > switchType ( OverviewPhotos ) ;
_mediaType - > hideStart ( ) ;
2014-08-21 16:18:56 +04:00
}
void MainWidget : : onVideosSelect ( ) {
2016-04-13 00:31:28 +03:00
if ( _overview ) _overview - > switchType ( OverviewVideos ) ;
_mediaType - > hideStart ( ) ;
2014-08-21 16:18:56 +04:00
}
2015-10-23 21:24:05 +02:00
void MainWidget : : onSongsSelect ( ) {
2016-04-13 00:31:28 +03:00
if ( _overview ) _overview - > switchType ( OverviewMusicFiles ) ;
_mediaType - > hideStart ( ) ;
2015-10-23 21:24:05 +02:00
}
2014-08-21 16:18:56 +04:00
void MainWidget : : onDocumentsSelect ( ) {
2016-04-13 00:31:28 +03:00
if ( _overview ) _overview - > switchType ( OverviewFiles ) ;
_mediaType - > hideStart ( ) ;
2014-08-21 16:18:56 +04:00
}
void MainWidget : : onAudiosSelect ( ) {
2016-04-13 00:31:28 +03:00
if ( _overview ) _overview - > switchType ( OverviewVoiceFiles ) ;
_mediaType - > hideStart ( ) ;
2014-08-21 16:18:56 +04:00
}
2015-08-28 18:15:56 +03:00
void MainWidget : : onLinksSelect ( ) {
2016-04-13 00:31:28 +03:00
if ( _overview ) _overview - > switchType ( OverviewLinks ) ;
_mediaType - > hideStart ( ) ;
2015-08-28 18:15:56 +03:00
}
2016-04-13 00:31:28 +03:00
Window : : TopBarWidget * MainWidget : : topBar ( ) {
return _topBar ;
2014-05-30 12:53:19 +04:00
}
2015-07-03 11:47:16 +03:00
PlayerWidget * MainWidget : : player ( ) {
2016-04-13 00:31:28 +03:00
return _player ;
2015-07-03 11:47:16 +03:00
}
2014-05-30 12:53:19 +04:00
void MainWidget : : onTopBarClick ( ) {
2016-05-19 15:03:51 +03:00
if ( _overview ) {
2016-04-13 00:31:28 +03:00
_overview - > topBarClick ( ) ;
2016-05-19 15:03:51 +03:00
} else if ( ! _wideSection ) {
2016-04-13 00:31:28 +03:00
_history - > topBarClick ( ) ;
2014-05-30 12:53:19 +04:00
}
}
2015-10-03 13:09:09 +03:00
void MainWidget : : onHistoryShown ( History * history , MsgId atMsgId ) {
2016-05-12 19:05:20 +03:00
if ( ( ! Adaptive : : OneColumn ( ) | | ! selectingPeer ( ) ) & & ( _overview | | history ) ) {
2016-04-13 00:31:28 +03:00
_topBar - > show ( ) ;
2014-05-30 12:53:19 +04:00
} else {
2016-04-13 00:31:28 +03:00
_topBar - > hide ( ) ;
2014-05-30 12:53:19 +04:00
}
resizeEvent ( 0 ) ;
2015-10-17 16:52:26 +02:00
if ( _a_show . animating ( ) ) {
2016-04-13 00:31:28 +03:00
_topBar - > hide ( ) ;
2015-09-01 16:50:56 +03:00
}
2015-11-13 18:14:33 +03:00
2015-10-03 13:09:09 +03:00
dlgUpdated ( history , atMsgId ) ;
2014-05-30 12:53:19 +04:00
}
2015-08-04 18:01:47 +03:00
void MainWidget : : searchInPeer ( PeerData * peer ) {
2016-04-13 00:31:28 +03:00
_dialogs - > searchInPeer ( peer ) ;
2016-02-08 17:54:55 +03:00
if ( Adaptive : : OneColumn ( ) ) {
2015-08-04 18:01:47 +03:00
dialogsToUp ( ) ;
2015-12-13 14:36:08 +03:00
Ui : : showChatsList ( ) ;
2016-02-08 17:54:55 +03:00
} else {
2016-04-13 00:31:28 +03:00
_dialogs - > activate ( ) ;
2015-08-04 18:01:47 +03:00
}
}
2014-05-30 12:53:19 +04:00
void MainWidget : : onUpdateNotifySettings ( ) {
2015-03-02 15:34:16 +03:00
if ( this ! = App : : main ( ) ) return ;
2014-05-30 12:53:19 +04:00
while ( ! updateNotifySettingPeers . isEmpty ( ) ) {
PeerData * peer = * updateNotifySettingPeers . begin ( ) ;
updateNotifySettingPeers . erase ( updateNotifySettingPeers . begin ( ) ) ;
if ( peer - > notify = = UnknownNotifySettings | | peer - > notify = = EmptyNotifySettings ) {
peer - > notify = new NotifySettings ( ) ;
}
2016-03-19 19:55:15 +03:00
MTP : : send ( MTPaccount_UpdateNotifySettings ( MTP_inputNotifyPeer ( peer - > input ) , MTP_inputPeerNotifySettings ( MTP_flags ( mtpCastFlags ( peer - > notify - > flags ) ) , MTP_int ( peer - > notify - > mute ) , MTP_string ( peer - > notify - > sound ) ) ) , RPCResponseHandler ( ) , 0 , updateNotifySettingPeers . isEmpty ( ) ? 0 : 10 ) ;
2014-05-30 12:53:19 +04:00
}
}
2015-09-21 23:57:42 +03:00
void MainWidget : : feedUpdateVector ( const MTPVector < MTPUpdate > & updates , bool skipMessageIds ) {
2016-04-08 14:44:35 +04:00
const auto & v ( updates . c_vector ( ) . v ) ;
2014-05-30 12:53:19 +04:00
for ( QVector < MTPUpdate > : : const_iterator i = v . cbegin ( ) , e = v . cend ( ) ; i ! = e ; + + i ) {
if ( skipMessageIds & & i - > type ( ) = = mtpc_updateMessageID ) continue ;
feedUpdate ( * i ) ;
}
}
void MainWidget : : feedMessageIds ( const MTPVector < MTPUpdate > & updates ) {
2016-04-08 14:44:35 +04:00
const auto & v ( updates . c_vector ( ) . v ) ;
2014-05-30 12:53:19 +04:00
for ( QVector < MTPUpdate > : : const_iterator i = v . cbegin ( ) , e = v . cend ( ) ; i ! = e ; + + i ) {
if ( i - > type ( ) = = mtpc_updateMessageID ) {
feedUpdate ( * i ) ;
}
}
}
bool MainWidget : : updateFail ( const RPCError & e ) {
2016-03-31 18:06:40 +04:00
App : : logOutDelayed ( ) ;
2014-05-30 12:53:19 +04:00
return true ;
}
void MainWidget : : updSetState ( int32 pts , int32 date , int32 qts , int32 seq ) {
2016-03-11 18:01:32 +03:00
if ( pts ) {
_ptsWaiter . init ( pts ) ;
}
if ( updDate < date & & ! _byMinChannelTimer . isActive ( ) ) {
updDate = date ;
}
2014-11-05 20:43:32 +03:00
if ( qts & & updQts < qts ) {
updQts = qts ;
}
if ( seq & & seq ! = updSeq ) {
updSeq = seq ;
if ( _bySeqTimer . isActive ( ) ) _bySeqTimer . stop ( ) ;
for ( QMap < int32 , MTPUpdates > : : iterator i = _bySeqUpdates . begin ( ) ; i ! = _bySeqUpdates . end ( ) ; ) {
int32 s = i . key ( ) ;
if ( s < = seq + 1 ) {
MTPUpdates v = i . value ( ) ;
i = _bySeqUpdates . erase ( i ) ;
if ( s = = seq + 1 ) {
2015-09-21 23:57:42 +03:00
return feedUpdates ( v ) ;
2014-11-05 20:43:32 +03:00
}
} else {
2015-03-13 16:01:25 +03:00
if ( ! _bySeqTimer . isActive ( ) ) _bySeqTimer . start ( WaitForSkippedTimeout ) ;
2014-11-05 20:43:32 +03:00
break ;
}
}
}
2014-05-30 12:53:19 +04:00
}
2015-09-13 11:41:27 +03:00
void MainWidget : : gotChannelDifference ( ChannelData * channel , const MTPupdates_ChannelDifference & diff ) {
_channelFailDifferenceTimeout . remove ( channel ) ;
2015-12-31 23:27:21 +08:00
2015-10-28 20:16:52 -04:00
int32 timeout = 0 ;
bool isFinal = true ;
2015-09-13 11:41:27 +03:00
switch ( diff . type ( ) ) {
case mtpc_updates_channelDifferenceEmpty : {
2016-04-08 14:44:35 +04:00
const auto & d ( diff . c_updates_channelDifferenceEmpty ( ) ) ;
2015-09-13 11:41:27 +03:00
if ( d . has_timeout ( ) ) timeout = d . vtimeout . v ;
2015-10-28 20:16:52 -04:00
isFinal = d . is_final ( ) ;
2015-09-13 20:27:29 +03:00
channel - > ptsInit ( d . vpts . v ) ;
2015-09-13 11:41:27 +03:00
} break ;
case mtpc_updates_channelDifferenceTooLong : {
2016-04-08 14:44:35 +04:00
const auto & d ( diff . c_updates_channelDifferenceTooLong ( ) ) ;
2015-09-13 11:41:27 +03:00
App : : feedUsers ( d . vusers ) ;
App : : feedChats ( d . vchats ) ;
2015-09-20 11:55:41 +03:00
History * h = App : : historyLoaded ( channel - > id ) ;
if ( h ) {
h - > setNotLoadedAtBottom ( ) ;
h - > asChannelHistory ( ) - > clearOther ( ) ;
}
App : : feedMsgs ( d . vmessages , NewMessageLast ) ;
if ( h ) {
2015-11-02 17:33:57 -05:00
MsgId topMsg = h - > isMegagroup ( ) ? d . vtop_message . v : d . vtop_important_message . v ;
if ( HistoryItem * item = App : : histItemById ( peerToChannel ( channel - > id ) , topMsg ) ) {
2015-09-13 11:41:27 +03:00
h - > setLastMessage ( item ) ;
}
2015-11-02 17:33:57 -05:00
int32 unreadCount = h - > isMegagroup ( ) ? d . vunread_count . v : d . vunread_important_count . v ;
2016-04-11 14:59:01 +04:00
if ( unreadCount > = h - > unreadCount ( ) ) {
2016-04-14 22:24:42 +03:00
h - > setUnreadCount ( unreadCount ) ;
2015-09-13 11:41:27 +03:00
h - > inboxReadBefore = d . vread_inbox_max_id . v + 1 ;
}
2015-09-20 11:55:41 +03:00
if ( d . vunread_count . v > = h - > asChannelHistory ( ) - > unreadCountAll ) {
h - > asChannelHistory ( ) - > unreadCountAll = d . vunread_count . v ;
h - > inboxReadBefore = d . vread_inbox_max_id . v + 1 ;
}
2016-04-13 00:31:28 +03:00
if ( _history - > peer ( ) = = channel ) {
_history - > updateToEndVisibility ( ) ;
_history - > preloadHistoryIfNeeded ( ) ;
2015-09-13 11:41:27 +03:00
}
2015-09-21 23:57:42 +03:00
h - > asChannelHistory ( ) - > getRangeDifference ( ) ;
2015-09-13 11:41:27 +03:00
}
if ( d . has_timeout ( ) ) timeout = d . vtimeout . v ;
2015-10-28 20:16:52 -04:00
isFinal = d . is_final ( ) ;
2015-09-13 20:27:29 +03:00
channel - > ptsInit ( d . vpts . v ) ;
2015-09-13 11:41:27 +03:00
} break ;
case mtpc_updates_channelDifference : {
2016-04-08 14:44:35 +04:00
const auto & d ( diff . c_updates_channelDifference ( ) ) ;
2015-09-13 11:41:27 +03:00
2016-05-25 15:09:05 +03:00
App : : feedUsersDelayed ( d . vusers ) ;
App : : feedChatsDelayed ( d . vchats ) ;
2015-12-31 23:27:21 +08:00
2015-09-21 23:57:42 +03:00
_handlingChannelDifference = true ;
2015-09-13 11:41:27 +03:00
feedMessageIds ( d . vother_updates ) ;
2015-09-21 23:57:42 +03:00
// feed messages and groups, copy from App::feedMsgs
History * h = App : : history ( channel - > id ) ;
2016-04-08 14:44:35 +04:00
const auto & vmsgs ( d . vnew_messages . c_vector ( ) . v ) ;
2015-09-21 23:57:42 +03:00
QMap < uint64 , int32 > msgsIds ;
for ( int32 i = 0 , l = vmsgs . size ( ) ; i < l ; + + i ) {
2016-04-08 14:44:35 +04:00
const auto & msg ( vmsgs . at ( i ) ) ;
2015-09-21 23:57:42 +03:00
switch ( msg . type ( ) ) {
case mtpc_message : {
2016-04-08 14:44:35 +04:00
const auto & d ( msg . c_message ( ) ) ;
2016-04-13 00:31:28 +03:00
if ( App : : checkEntitiesAndViewsUpdate ( d ) ) { // new message, index my forwarded messages to links _overview, already in blocks
2015-10-15 02:15:28 +02:00
LOG ( ( " Skipping message, because it is already in blocks! " ) ) ;
} else {
msgsIds . insert ( ( uint64 ( uint32 ( d . vid . v ) ) < < 32 ) | uint64 ( i ) , i + 1 ) ;
}
2015-09-21 23:57:42 +03:00
} break ;
case mtpc_messageEmpty : msgsIds . insert ( ( uint64 ( uint32 ( msg . c_messageEmpty ( ) . vid . v ) ) < < 32 ) | uint64 ( i ) , i + 1 ) ; break ;
case mtpc_messageService : msgsIds . insert ( ( uint64 ( uint32 ( msg . c_messageService ( ) . vid . v ) ) < < 32 ) | uint64 ( i ) , i + 1 ) ; break ;
}
}
2016-04-08 14:44:35 +04:00
const auto & vother ( d . vother_updates . c_vector ( ) . v ) ;
2015-09-21 23:57:42 +03:00
for ( int32 i = 0 , l = vother . size ( ) ; i < l ; + + i ) {
if ( vother . at ( i ) . type ( ) = = mtpc_updateChannelGroup ) {
2016-04-08 14:44:35 +04:00
const auto & updateGroup ( vother . at ( i ) . c_updateChannelGroup ( ) ) ;
2015-09-21 23:57:42 +03:00
if ( updateGroup . vgroup . type ( ) = = mtpc_messageGroup ) {
2016-04-08 14:44:35 +04:00
const auto & group ( updateGroup . vgroup . c_messageGroup ( ) ) ;
2015-09-21 23:57:42 +03:00
if ( updateGroup . vchannel_id . v ! = peerToChannel ( channel - > id ) ) {
LOG ( ( " API Error: updateChannelGroup with invalid channel_id returned in channelDifference, channelId: %1, channel_id: %2 " ) . arg ( peerToChannel ( channel - > id ) ) . arg ( updateGroup . vchannel_id . v ) ) ;
continue ;
}
msgsIds . insert ( ( uint64 ( ( uint32 ( group . vmin_id . v ) + uint32 ( group . vmax_id . v ) ) / 2 ) < < 32 ) , - i - 1 ) ;
}
}
}
for ( QMap < uint64 , int32 > : : const_iterator i = msgsIds . cbegin ( ) , e = msgsIds . cend ( ) ; i ! = e ; + + i ) {
if ( i . value ( ) > 0 ) { // add message
2016-04-08 14:44:35 +04:00
const auto & msg ( vmsgs . at ( i . value ( ) - 1 ) ) ;
2015-09-21 23:57:42 +03:00
if ( channel - > id ! = peerFromMessage ( msg ) ) {
LOG ( ( " API Error: message with invalid peer returned in channelDifference, channelId: %1, peer: %2 " ) . arg ( peerToChannel ( channel - > id ) ) . arg ( peerFromMessage ( msg ) ) ) ;
continue ; // wtf
}
h - > addNewMessage ( msg , NewMessageUnread ) ;
} else { // add group
2016-04-08 14:44:35 +04:00
const auto & updateGroup ( vother . at ( - i . value ( ) - 1 ) . c_updateChannelGroup ( ) ) ;
2015-09-21 23:57:42 +03:00
h - > asChannelHistory ( ) - > addNewGroup ( updateGroup . vgroup ) ;
}
}
feedUpdateVector ( d . vother_updates , true ) ;
_handlingChannelDifference = false ;
2015-09-13 11:41:27 +03:00
if ( d . has_timeout ( ) ) timeout = d . vtimeout . v ;
2015-10-28 20:16:52 -04:00
isFinal = d . is_final ( ) ;
2015-09-13 20:27:29 +03:00
channel - > ptsInit ( d . vpts . v ) ;
2015-09-13 11:41:27 +03:00
} break ;
}
channel - > ptsSetRequesting ( false ) ;
2015-10-28 20:16:52 -04:00
if ( ! isFinal ) {
2015-09-13 11:41:27 +03:00
MTP_LOG ( 0 , ( " getChannelDifference { good - after not final channelDifference was received }%1 " ) . arg ( cTestMode ( ) ? " TESTMODE " : " " ) ) ;
getChannelDifference ( channel ) ;
2015-09-20 11:55:41 +03:00
} else if ( activePeer ( ) = = channel ) {
2015-09-20 12:54:22 +03:00
channel - > ptsWaitingForShortPoll ( timeout ? ( timeout * 1000 ) : WaitForChannelGetDifference ) ;
2015-09-13 11:41:27 +03:00
}
2016-05-25 15:09:05 +03:00
Notify : : peerUpdatedSendDelayed ( ) ;
2015-09-13 11:41:27 +03:00
}
2015-09-21 23:57:42 +03:00
void MainWidget : : gotRangeDifference ( ChannelData * channel , const MTPupdates_ChannelDifference & diff ) {
2015-10-28 20:16:52 -04:00
int32 nextRequestPts = 0 ;
bool isFinal = true ;
2015-09-21 23:57:42 +03:00
switch ( diff . type ( ) ) {
case mtpc_updates_channelDifferenceEmpty : {
2016-04-08 14:44:35 +04:00
const auto & d ( diff . c_updates_channelDifferenceEmpty ( ) ) ;
2015-09-21 23:57:42 +03:00
nextRequestPts = d . vpts . v ;
2015-10-28 20:16:52 -04:00
isFinal = d . is_final ( ) ;
2015-09-21 23:57:42 +03:00
} break ;
case mtpc_updates_channelDifferenceTooLong : {
2016-04-08 14:44:35 +04:00
const auto & d ( diff . c_updates_channelDifferenceTooLong ( ) ) ;
2015-09-21 23:57:42 +03:00
2016-05-25 15:09:05 +03:00
App : : feedUsersDelayed ( d . vusers ) ;
App : : feedChatsDelayed ( d . vchats ) ;
2015-09-21 23:57:42 +03:00
nextRequestPts = d . vpts . v ;
2015-10-28 20:16:52 -04:00
isFinal = d . is_final ( ) ;
2015-09-21 23:57:42 +03:00
} break ;
case mtpc_updates_channelDifference : {
2016-04-08 14:44:35 +04:00
const auto & d ( diff . c_updates_channelDifference ( ) ) ;
2015-09-21 23:57:42 +03:00
2016-05-25 15:09:05 +03:00
App : : feedUsersDelayed ( d . vusers ) ;
App : : feedChatsDelayed ( d . vchats ) ;
2015-09-21 23:57:42 +03:00
_handlingChannelDifference = true ;
feedMessageIds ( d . vother_updates ) ;
App : : feedMsgs ( d . vnew_messages , NewMessageUnread ) ;
feedUpdateVector ( d . vother_updates , true ) ;
_handlingChannelDifference = false ;
nextRequestPts = d . vpts . v ;
2015-10-28 20:16:52 -04:00
isFinal = d . is_final ( ) ;
2015-09-21 23:57:42 +03:00
} break ;
}
2015-10-28 20:16:52 -04:00
if ( ! isFinal ) {
2015-09-21 23:57:42 +03:00
if ( History * h = App : : historyLoaded ( channel - > id ) ) {
MTP_LOG ( 0 , ( " getChannelDifference { good - after not final channelDifference was received, validating history part }%1 " ) . arg ( cTestMode ( ) ? " TESTMODE " : " " ) ) ;
h - > asChannelHistory ( ) - > getRangeDifferenceNext ( nextRequestPts ) ;
}
}
2016-05-25 15:09:05 +03:00
Notify : : peerUpdatedSendDelayed ( ) ;
2015-09-21 23:57:42 +03:00
}
2015-09-13 11:41:27 +03:00
bool MainWidget : : failChannelDifference ( ChannelData * channel , const RPCError & error ) {
2016-04-08 14:44:35 +04:00
if ( MTP : : isDefaultHandledError ( error ) ) return false ;
2015-09-13 11:41:27 +03:00
LOG ( ( " RPC Error in getChannelDifference: %1 %2: %3 " ) . arg ( error . code ( ) ) . arg ( error . type ( ) ) . arg ( error . description ( ) ) ) ;
failDifferenceStartTimerFor ( channel ) ;
return true ;
}
2014-05-30 12:53:19 +04:00
void MainWidget : : gotState ( const MTPupdates_State & state ) {
2016-04-08 14:44:35 +04:00
const auto & d ( state . c_updates_state ( ) ) ;
2014-05-30 12:53:19 +04:00
updSetState ( d . vpts . v , d . vdate . v , d . vqts . v , d . vseq . v ) ;
2014-11-12 23:30:26 +03:00
_lastUpdateTime = getms ( true ) ;
2014-05-30 12:53:19 +04:00
noUpdatesTimer . start ( NoUpdatesTimeout ) ;
2015-09-13 11:41:27 +03:00
_ptsWaiter . setRequesting ( false ) ;
2014-05-30 12:53:19 +04:00
2016-04-13 00:31:28 +03:00
_dialogs - > loadDialogs ( ) ;
2015-01-26 16:04:41 +03:00
updateOnline ( ) ;
2015-06-30 01:09:23 +03:00
2016-05-25 15:09:05 +03:00
Notify : : peerUpdatedSendDelayed ( ) ;
2014-05-30 12:53:19 +04:00
}
void MainWidget : : gotDifference ( const MTPupdates_Difference & diff ) {
2014-11-05 20:43:32 +03:00
_failDifferenceTimeout = 1 ;
2014-05-30 12:53:19 +04:00
switch ( diff . type ( ) ) {
case mtpc_updates_differenceEmpty : {
2016-04-08 14:44:35 +04:00
const auto & d ( diff . c_updates_differenceEmpty ( ) ) ;
2015-09-13 11:41:27 +03:00
updSetState ( _ptsWaiter . current ( ) , d . vdate . v , updQts , d . vseq . v ) ;
2014-05-30 12:53:19 +04:00
2014-11-12 23:30:26 +03:00
_lastUpdateTime = getms ( true ) ;
2014-05-30 12:53:19 +04:00
noUpdatesTimer . start ( NoUpdatesTimeout ) ;
2014-11-22 12:45:04 +03:00
2015-09-13 11:41:27 +03:00
_ptsWaiter . setRequesting ( false ) ;
2014-05-30 12:53:19 +04:00
} break ;
case mtpc_updates_differenceSlice : {
2016-04-08 14:44:35 +04:00
const auto & d ( diff . c_updates_differenceSlice ( ) ) ;
2014-05-30 12:53:19 +04:00
feedDifference ( d . vusers , d . vchats , d . vnew_messages , d . vother_updates ) ;
2016-04-08 14:44:35 +04:00
const auto & s ( d . vintermediate_state . c_updates_state ( ) ) ;
2014-05-30 12:53:19 +04:00
updSetState ( s . vpts . v , s . vdate . v , s . vqts . v , s . vseq . v ) ;
2015-09-13 11:41:27 +03:00
_ptsWaiter . setRequesting ( false ) ;
2014-05-30 12:53:19 +04:00
2015-04-30 16:53:36 +03:00
MTP_LOG ( 0 , ( " getDifference { good - after a slice of difference was received }%1 " ) . arg ( cTestMode ( ) ? " TESTMODE " : " " ) ) ;
2014-05-30 12:53:19 +04:00
getDifference ( ) ;
} break ;
case mtpc_updates_difference : {
2016-04-08 14:44:35 +04:00
const auto & d ( diff . c_updates_difference ( ) ) ;
2014-05-30 12:53:19 +04:00
feedDifference ( d . vusers , d . vchats , d . vnew_messages , d . vother_updates ) ;
gotState ( d . vstate ) ;
} break ;
} ;
2016-05-25 15:09:05 +03:00
Notify : : peerUpdatedSendDelayed ( ) ;
2014-05-30 12:53:19 +04:00
}
2015-09-13 11:41:27 +03:00
bool MainWidget : : getDifferenceTimeChanged ( ChannelData * channel , int32 ms , ChannelGetDifferenceTime & channelCurTime , uint64 & curTime ) {
if ( channel ) {
if ( ms < = 0 ) {
ChannelGetDifferenceTime : : iterator i = channelCurTime . find ( channel ) ;
if ( i ! = channelCurTime . cend ( ) ) {
channelCurTime . erase ( i ) ;
} else {
return false ;
}
} else {
uint64 when = getms ( true ) + ms ;
ChannelGetDifferenceTime : : iterator i = channelCurTime . find ( channel ) ;
if ( i ! = channelCurTime . cend ( ) ) {
if ( i . value ( ) > when ) {
i . value ( ) = when ;
} else {
return false ;
}
} else {
channelCurTime . insert ( channel , when ) ;
}
}
} else {
if ( ms < = 0 ) {
if ( curTime ) {
curTime = 0 ;
} else {
return false ;
}
} else {
uint64 when = getms ( true ) + ms ;
if ( ! curTime | | curTime > when ) {
curTime = when ;
} else {
return false ;
}
}
}
return true ;
}
void MainWidget : : ptsWaiterStartTimerFor ( ChannelData * channel , int32 ms ) {
if ( getDifferenceTimeChanged ( channel , ms , _channelGetDifferenceTimeByPts , _getDifferenceTimeByPts ) ) {
onGetDifferenceTimeByPts ( ) ;
}
2015-03-13 16:01:25 +03:00
}
2015-09-13 11:41:27 +03:00
void MainWidget : : failDifferenceStartTimerFor ( ChannelData * channel ) {
int32 ms = 0 ;
ChannelFailDifferenceTimeout : : iterator i ;
if ( channel ) {
i = _channelFailDifferenceTimeout . find ( channel ) ;
if ( i = = _channelFailDifferenceTimeout . cend ( ) ) {
i = _channelFailDifferenceTimeout . insert ( channel , 1 ) ;
2015-03-13 16:01:25 +03:00
}
2015-09-13 11:41:27 +03:00
ms = i . value ( ) * 1000 ;
} else {
ms = _failDifferenceTimeout * 1000 ;
}
if ( getDifferenceTimeChanged ( channel , ms , _channelGetDifferenceTimeAfterFail , _getDifferenceTimeAfterFail ) ) {
onGetDifferenceTimeAfterFail ( ) ;
}
if ( channel ) {
if ( i . value ( ) < 64 ) i . value ( ) * = 2 ;
} else {
if ( _failDifferenceTimeout < 64 ) _failDifferenceTimeout * = 2 ;
2015-03-13 16:01:25 +03:00
}
}
2015-09-13 11:41:27 +03:00
bool MainWidget : : ptsUpdated ( int32 pts , int32 ptsCount ) { // return false if need to save that update and apply later
return _ptsWaiter . updated ( 0 , pts , ptsCount ) ;
2015-03-13 16:01:25 +03:00
}
2015-09-13 11:41:27 +03:00
bool MainWidget : : ptsUpdated ( int32 pts , int32 ptsCount , const MTPUpdates & updates ) {
return _ptsWaiter . updated ( 0 , pts , ptsCount , updates ) ;
}
2015-03-13 16:01:25 +03:00
2015-09-13 11:41:27 +03:00
bool MainWidget : : ptsUpdated ( int32 pts , int32 ptsCount , const MTPUpdate & update ) {
return _ptsWaiter . updated ( 0 , pts , ptsCount , update ) ;
2014-05-30 12:53:19 +04:00
}
2015-09-20 12:54:22 +03:00
void MainWidget : : ptsApplySkippedUpdates ( ) {
return _ptsWaiter . applySkippedUpdates ( 0 ) ;
}
2014-05-30 12:53:19 +04:00
void MainWidget : : feedDifference ( const MTPVector < MTPUser > & users , const MTPVector < MTPChat > & chats , const MTPVector < MTPMessage > & msgs , const MTPVector < MTPUpdate > & other ) {
2015-03-02 15:34:16 +03:00
App : : wnd ( ) - > checkAutoLock ( ) ;
2016-05-25 15:09:05 +03:00
App : : feedUsersDelayed ( users ) ;
App : : feedChatsDelayed ( chats ) ;
2014-05-30 12:53:19 +04:00
feedMessageIds ( other ) ;
2015-09-20 11:55:41 +03:00
App : : feedMsgs ( msgs , NewMessageUnread ) ;
2015-09-21 23:57:42 +03:00
feedUpdateVector ( other , true ) ;
2016-04-13 00:31:28 +03:00
_history - > peerMessagesUpdated ( ) ;
2014-05-30 12:53:19 +04:00
}
2015-04-04 23:01:34 +03:00
bool MainWidget : : failDifference ( const RPCError & error ) {
2016-04-08 14:44:35 +04:00
if ( MTP : : isDefaultHandledError ( error ) ) return false ;
2015-04-04 23:01:34 +03:00
2015-09-13 11:41:27 +03:00
LOG ( ( " RPC Error in getDifference: %1 %2: %3 " ) . arg ( error . code ( ) ) . arg ( error . type ( ) ) . arg ( error . description ( ) ) ) ;
failDifferenceStartTimerFor ( 0 ) ;
2014-11-05 20:43:32 +03:00
return true ;
}
2015-09-13 11:41:27 +03:00
void MainWidget : : onGetDifferenceTimeByPts ( ) {
if ( ! MTP : : authedId ( ) ) return ;
uint64 now = getms ( true ) , wait = 0 ;
if ( _getDifferenceTimeByPts ) {
if ( _getDifferenceTimeByPts > now ) {
wait = _getDifferenceTimeByPts - now ;
} else {
getDifference ( ) ;
}
}
for ( ChannelGetDifferenceTime : : iterator i = _channelGetDifferenceTimeByPts . begin ( ) ; i ! = _channelGetDifferenceTimeByPts . cend ( ) ; ) {
if ( i . value ( ) > now ) {
2015-09-13 20:27:29 +03:00
wait = wait ? qMin ( wait , i . value ( ) - now ) : ( i . value ( ) - now ) ;
2015-09-13 11:41:27 +03:00
+ + i ;
} else {
2015-09-13 20:27:29 +03:00
getChannelDifference ( i . key ( ) , GetChannelDifferenceFromPtsGap ) ;
2015-09-13 11:41:27 +03:00
i = _channelGetDifferenceTimeByPts . erase ( i ) ;
}
}
if ( wait ) {
_byPtsTimer . start ( wait ) ;
} else {
_byPtsTimer . stop ( ) ;
}
}
void MainWidget : : onGetDifferenceTimeAfterFail ( ) {
if ( ! MTP : : authedId ( ) ) return ;
uint64 now = getms ( true ) , wait = 0 ;
if ( _getDifferenceTimeAfterFail ) {
if ( _getDifferenceTimeAfterFail > now ) {
wait = _getDifferenceTimeAfterFail - now ;
} else {
_ptsWaiter . setRequesting ( false ) ;
MTP_LOG ( 0 , ( " getDifference { force - after get difference failed }%1 " ) . arg ( cTestMode ( ) ? " TESTMODE " : " " ) ) ;
getDifference ( ) ;
}
}
for ( ChannelGetDifferenceTime : : iterator i = _channelGetDifferenceTimeAfterFail . begin ( ) ; i ! = _channelGetDifferenceTimeAfterFail . cend ( ) ; ) {
if ( i . value ( ) > now ) {
2015-09-13 20:27:29 +03:00
wait = wait ? qMin ( wait , i . value ( ) - now ) : ( i . value ( ) - now ) ;
2015-09-13 11:41:27 +03:00
+ + i ;
} else {
2015-09-13 20:27:29 +03:00
getChannelDifference ( i . key ( ) , GetChannelDifferenceFromFail ) ;
2015-09-13 11:41:27 +03:00
i = _channelGetDifferenceTimeAfterFail . erase ( i ) ;
}
}
if ( wait ) {
_failDifferenceTimer . start ( wait ) ;
} else {
_failDifferenceTimer . stop ( ) ;
2014-05-30 12:53:19 +04:00
}
}
void MainWidget : : getDifference ( ) {
2015-03-02 15:34:16 +03:00
if ( this ! = App : : main ( ) ) return ;
2015-09-13 11:41:27 +03:00
_getDifferenceTimeByPts = 0 ;
2014-11-12 23:30:26 +03:00
LOG ( ( " Getting difference! no updates timer: %1, remains: %2 " ) . arg ( noUpdatesTimer . isActive ( ) ? 1 : 0 ) . arg ( noUpdatesTimer . remainingTime ( ) ) ) ;
2015-09-13 11:41:27 +03:00
if ( _ptsWaiter . requesting ( ) ) return ;
2014-11-05 20:43:32 +03:00
_bySeqUpdates . clear ( ) ;
_bySeqTimer . stop ( ) ;
noUpdatesTimer . stop ( ) ;
2015-09-13 11:41:27 +03:00
_getDifferenceTimeAfterFail = 0 ;
2014-11-05 20:43:32 +03:00
2015-09-13 11:41:27 +03:00
LOG ( ( " Getting difference for %1, %2 " ) . arg ( _ptsWaiter . current ( ) ) . arg ( updDate ) ) ;
_ptsWaiter . setRequesting ( true ) ;
MTP : : send ( MTPupdates_GetDifference ( MTP_int ( _ptsWaiter . current ( ) ) , MTP_int ( updDate ) , MTP_int ( updQts ) ) , rpcDone ( & MainWidget : : gotDifference ) , rpcFail ( & MainWidget : : failDifference ) ) ;
}
void MainWidget : : getChannelDifference ( ChannelData * channel , GetChannelDifferenceFrom from ) {
if ( this ! = App : : main ( ) | | ! channel ) return ;
if ( from ! = GetChannelDifferenceFromPtsGap ) {
_channelGetDifferenceTimeByPts . remove ( channel ) ;
}
LOG ( ( " Getting channel difference! " ) ) ;
if ( ! channel - > ptsInited ( ) | | channel - > ptsRequesting ( ) ) return ;
if ( from ! = GetChannelDifferenceFromFail ) {
_channelGetDifferenceTimeAfterFail . remove ( channel ) ;
}
LOG ( ( " Getting channel difference for %1 " ) . arg ( channel - > pts ( ) ) ) ;
channel - > ptsSetRequesting ( true ) ;
2015-09-20 12:54:22 +03:00
2015-09-20 11:55:41 +03:00
MTPChannelMessagesFilter filter ;
if ( activePeer ( ) = = channel ) {
filter = MTP_channelMessagesFilterEmpty ( ) ;
} else {
2015-09-21 23:57:42 +03:00
filter = MTP_channelMessagesFilterEmpty ( ) ; //MTP_channelMessagesFilterCollapsed(); - not supported
2015-09-20 11:55:41 +03:00
if ( History * history = App : : historyLoaded ( channel - > id ) ) {
2015-11-02 17:33:57 -05:00
if ( ! history - > isMegagroup ( ) & & ! history - > asChannelHistory ( ) - > onlyImportant ( ) ) {
2015-09-20 11:55:41 +03:00
MsgId fixInScrollMsgId = 0 ;
int32 fixInScrollMsgTop = 0 ;
history - > asChannelHistory ( ) - > getSwitchReadyFor ( SwitchAtTopMsgId , fixInScrollMsgId , fixInScrollMsgTop ) ;
history - > getReadyFor ( ShowAtTheEndMsgId , fixInScrollMsgId , fixInScrollMsgTop ) ;
2016-03-21 21:40:00 +03:00
history - > forgetScrollState ( ) ;
2015-09-20 11:55:41 +03:00
}
}
}
2015-09-21 23:57:42 +03:00
MTP : : send ( MTPupdates_GetChannelDifference ( channel - > inputChannel , filter , MTP_int ( channel - > pts ( ) ) , MTP_int ( MTPChannelGetDifferenceLimit ) ) , rpcDone ( & MainWidget : : gotChannelDifference , channel ) , rpcFail ( & MainWidget : : failChannelDifference , channel ) ) ;
2014-05-30 12:53:19 +04:00
}
2015-04-16 17:59:42 +03:00
void MainWidget : : mtpPing ( ) {
MTP : : ping ( ) ;
}
2014-05-30 12:53:19 +04:00
void MainWidget : : start ( const MTPUser & user ) {
2015-06-10 15:48:26 +03:00
int32 uid = user . c_user ( ) . vid . v ;
2015-03-02 15:34:16 +03:00
if ( MTP : : authedId ( ) ! = uid ) {
MTP : : authed ( uid ) ;
Local : : writeMtpData ( ) ;
}
2015-08-07 15:11:50 +03:00
Local : : readSavedPeers ( ) ;
2015-01-26 16:04:41 +03:00
cSetOtherOnline ( 0 ) ;
2014-11-05 20:43:32 +03:00
App : : feedUsers ( MTP_vector < MTPUser > ( 1 , user ) ) ;
2014-05-30 12:53:19 +04:00
MTP : : send ( MTPupdates_GetState ( ) , rpcDone ( & MainWidget : : gotState ) ) ;
update ( ) ;
2014-12-03 16:10:32 +03:00
if ( ! cStartUrl ( ) . isEmpty ( ) ) {
openLocalUrl ( cStartUrl ( ) ) ;
cSetStartUrl ( QString ( ) ) ;
}
2014-12-12 19:27:03 +03:00
_started = true ;
App : : wnd ( ) - > sendServiceHistoryRequest ( ) ;
2015-05-19 18:46:45 +03:00
Local : : readStickers ( ) ;
2015-12-28 00:37:48 +03:00
Local : : readSavedGifs ( ) ;
2016-04-13 00:31:28 +03:00
_history - > start ( ) ;
2014-12-12 19:27:03 +03:00
}
bool MainWidget : : started ( ) {
return _started ;
2014-12-03 16:10:32 +03:00
}
void MainWidget : : openLocalUrl ( const QString & url ) {
2015-04-22 14:21:45 +03:00
QString u ( url . trimmed ( ) ) ;
2015-06-27 16:02:00 +03:00
if ( u . startsWith ( qstr ( " tg://resolve " ) , Qt : : CaseInsensitive ) ) {
2016-02-17 19:37:21 +03:00
QRegularExpressionMatch m = QRegularExpression ( qsl ( " ^tg://resolve/? \\ ?domain=([a-zA-Z0-9 \\ . \\ _]+)(&|$) " ) , QRegularExpression : : CaseInsensitiveOption ) . match ( u ) ;
2015-04-22 14:21:45 +03:00
if ( m . hasMatch ( ) ) {
2016-02-17 19:37:21 +03:00
QString params = u . mid ( m . capturedLength ( 0 ) ) ;
QString start , startToken ;
QRegularExpressionMatch startparam = QRegularExpression ( qsl ( " (^|&)(start|startgroup)=([a-zA-Z0-9 \\ . \\ _ \\ -]+)(&|$) " ) ) . match ( params ) ;
if ( startparam . hasMatch ( ) ) {
start = startparam . captured ( 2 ) ;
startToken = startparam . captured ( 3 ) ;
}
MsgId post = ( start = = qsl ( " startgroup " ) ) ? ShowAtProfileMsgId : ShowAtUnreadMsgId ;
QRegularExpressionMatch postparam = QRegularExpression ( qsl ( " (^|&)post=( \\ d+)(&|$) " ) ) . match ( params ) ;
if ( postparam . hasMatch ( ) ) {
post = postparam . captured ( 2 ) . toInt ( ) ;
}
openPeerByName ( m . captured ( 1 ) , post , startToken ) ;
2015-04-22 14:21:45 +03:00
}
2015-06-27 16:02:00 +03:00
} else if ( u . startsWith ( qstr ( " tg://join " ) , Qt : : CaseInsensitive ) ) {
2015-06-17 00:01:43 +03:00
QRegularExpressionMatch m = QRegularExpression ( qsl ( " ^tg://join/? \\ ?invite=([a-zA-Z0-9 \\ . \\ _ \\ -]+)(&|$) " ) , QRegularExpression : : CaseInsensitiveOption ) . match ( u ) ;
2015-04-22 14:21:45 +03:00
if ( m . hasMatch ( ) ) {
2015-04-30 16:53:36 +03:00
joinGroupByHash ( m . captured ( 1 ) ) ;
2015-04-22 14:21:45 +03:00
}
2015-06-27 16:02:00 +03:00
} else if ( u . startsWith ( qstr ( " tg://addstickers " ) , Qt : : CaseInsensitive ) ) {
2015-06-17 00:01:43 +03:00
QRegularExpressionMatch m = QRegularExpression ( qsl ( " ^tg://addstickers/? \\ ?set=([a-zA-Z0-9 \\ . \\ _]+)(&|$) " ) , QRegularExpression : : CaseInsensitiveOption ) . match ( u ) ;
2015-05-19 18:46:45 +03:00
if ( m . hasMatch ( ) ) {
stickersBox ( MTP_inputStickerSetShortName ( MTP_string ( m . captured ( 1 ) ) ) ) ;
}
2015-10-18 14:49:34 +02:00
} else if ( u . startsWith ( qstr ( " tg://msg_url " ) , Qt : : CaseInsensitive ) ) {
QRegularExpressionMatch m = QRegularExpression ( qsl ( " ^tg://msg_url/? \\ ?(.+)(#|$) " ) , QRegularExpression : : CaseInsensitiveOption ) . match ( u ) ;
if ( m . hasMatch ( ) ) {
QStringList params = m . captured ( 1 ) . split ( ' & ' ) ;
QString url , text ;
for ( int32 i = 0 , l = params . size ( ) ; i < l ; + + i ) {
if ( params . at ( i ) . startsWith ( qstr ( " url= " ) , Qt : : CaseInsensitive ) ) {
url = myUrlDecode ( params . at ( i ) . mid ( 4 ) ) ;
} else if ( params . at ( i ) . startsWith ( qstr ( " text= " ) , Qt : : CaseInsensitive ) ) {
text = myUrlDecode ( params . at ( i ) . mid ( 5 ) ) ;
}
}
if ( ! url . isEmpty ( ) ) {
shareUrlLayer ( url , text ) ;
}
}
2014-12-03 16:10:32 +03:00
}
}
2016-02-17 19:37:21 +03:00
void MainWidget : : openPeerByName ( const QString & username , MsgId msgId , const QString & startToken ) {
2015-05-20 22:28:24 +03:00
App : : wnd ( ) - > hideMediaview ( ) ;
2015-09-06 13:17:09 +03:00
PeerData * peer = App : : peerByName ( username ) ;
if ( peer ) {
2016-02-17 19:37:21 +03:00
if ( msgId = = ShowAtProfileMsgId & & ! peer - > isChannel ( ) ) {
2015-09-06 13:17:09 +03:00
if ( peer - > isUser ( ) & & peer - > asUser ( ) - > botInfo & & ! peer - > asUser ( ) - > botInfo - > cantJoinGroups & & ! startToken . isEmpty ( ) ) {
peer - > asUser ( ) - > botInfo - > startGroupToken = startToken ;
2015-12-07 21:09:05 +03:00
Ui : : showLayer ( new ContactsBox ( peer - > asUser ( ) ) ) ;
2016-04-06 15:07:05 +04:00
} else if ( peer - > isUser ( ) & & peer - > asUser ( ) - > botInfo ) {
// Always open bot chats, even from mention links.
Ui : : showPeerHistoryAsync ( peer - > id , ShowAtUnreadMsgId ) ;
2015-06-17 22:43:03 +03:00
} else {
2016-05-19 15:03:51 +03:00
Ui : : showPeerProfile ( peer ) ;
2015-06-17 22:43:03 +03:00
}
2015-03-19 12:18:19 +03:00
} else {
2016-02-18 19:36:33 +03:00
if ( msgId = = ShowAtProfileMsgId | | ! peer - > isChannel ( ) ) { // show specific posts only in channels / supergroups
2016-02-17 19:37:21 +03:00
msgId = ShowAtUnreadMsgId ;
}
2015-09-06 13:17:09 +03:00
if ( peer - > isUser ( ) & & peer - > asUser ( ) - > botInfo ) {
peer - > asUser ( ) - > botInfo - > startToken = startToken ;
2016-04-13 00:31:28 +03:00
if ( peer = = _history - > peer ( ) ) {
_history - > updateControlsVisibility ( ) ;
_history - > resizeEvent ( 0 ) ;
2015-06-19 15:39:33 +03:00
}
}
2016-02-17 19:37:21 +03:00
Ui : : showPeerHistoryAsync ( peer - > id , msgId ) ;
2015-03-19 12:18:19 +03:00
}
2014-12-03 16:10:32 +03:00
} else {
2016-02-17 19:37:21 +03:00
MTP : : send ( MTPcontacts_ResolveUsername ( MTP_string ( username ) ) , rpcDone ( & MainWidget : : usernameResolveDone , qMakePair ( msgId , startToken ) ) , rpcFail ( & MainWidget : : usernameResolveFail , username ) ) ;
2014-12-03 16:10:32 +03:00
}
}
2015-04-30 16:53:36 +03:00
void MainWidget : : joinGroupByHash ( const QString & hash ) {
2015-05-20 22:28:24 +03:00
App : : wnd ( ) - > hideMediaview ( ) ;
2015-04-30 16:53:36 +03:00
MTP : : send ( MTPmessages_CheckChatInvite ( MTP_string ( hash ) ) , rpcDone ( & MainWidget : : inviteCheckDone , hash ) , rpcFail ( & MainWidget : : inviteCheckFail ) ) ;
}
2015-05-19 18:46:45 +03:00
void MainWidget : : stickersBox ( const MTPInputStickerSet & set ) {
2015-05-20 22:28:24 +03:00
App : : wnd ( ) - > hideMediaview ( ) ;
2015-05-19 18:46:45 +03:00
StickerSetBox * box = new StickerSetBox ( set ) ;
connect ( box , SIGNAL ( installed ( uint64 ) ) , this , SLOT ( onStickersInstalled ( uint64 ) ) ) ;
2015-12-07 21:09:05 +03:00
Ui : : showLayer ( box ) ;
2015-05-19 18:46:45 +03:00
}
void MainWidget : : onStickersInstalled ( uint64 setId ) {
emit stickersUpdated ( ) ;
2016-04-13 00:31:28 +03:00
_history - > stickersInstalled ( setId ) ;
2015-05-19 18:46:45 +03:00
}
2015-09-21 23:57:42 +03:00
void MainWidget : : onFullPeerUpdated ( PeerData * peer ) {
emit peerUpdated ( peer ) ;
}
void MainWidget : : onSelfParticipantUpdated ( ChannelData * channel ) {
History * h = App : : historyLoaded ( channel - > id ) ;
if ( _updatedChannels . contains ( channel ) ) {
_updatedChannels . remove ( channel ) ;
if ( ( h ? h : App : : history ( channel - > id ) ) - > isEmpty ( ) ) {
checkPeerHistory ( channel ) ;
} else {
2015-09-25 10:47:32 +03:00
h - > asChannelHistory ( ) - > checkJoinedMessage ( true ) ;
2016-04-13 00:31:28 +03:00
_history - > peerMessagesUpdated ( channel - > id ) ;
2015-09-21 23:57:42 +03:00
}
} else if ( h ) {
h - > asChannelHistory ( ) - > checkJoinedMessage ( ) ;
2016-04-13 00:31:28 +03:00
_history - > peerMessagesUpdated ( channel - > id ) ;
2015-09-21 23:57:42 +03:00
}
}
2015-10-01 17:05:05 +03:00
bool MainWidget : : contentOverlapped ( const QRect & globalRect ) {
2016-04-13 00:31:28 +03:00
return ( _history - > contentOverlapped ( globalRect ) | |
_mediaType - > overlaps ( globalRect ) ) ;
2015-10-01 17:05:05 +03:00
}
2016-02-17 19:37:21 +03:00
void MainWidget : : usernameResolveDone ( QPair < MsgId , QString > msgIdAndStartToken , const MTPcontacts_ResolvedPeer & result ) {
2015-12-07 21:09:05 +03:00
Ui : : hideLayer ( ) ;
2015-09-06 13:17:09 +03:00
if ( result . type ( ) ! = mtpc_contacts_resolvedPeer ) return ;
2016-04-08 14:44:35 +04:00
const auto & d ( result . c_contacts_resolvedPeer ( ) ) ;
2015-09-06 13:17:09 +03:00
App : : feedUsers ( d . vusers ) ;
App : : feedChats ( d . vchats ) ;
PeerId peerId = peerFromMTP ( d . vpeer ) ;
if ( ! peerId ) return ;
PeerData * peer = App : : peer ( peerId ) ;
2016-02-17 19:37:21 +03:00
MsgId msgId = msgIdAndStartToken . first ;
QString startToken = msgIdAndStartToken . second ;
if ( msgId = = ShowAtProfileMsgId & & ! peer - > isChannel ( ) ) {
if ( peer - > isUser ( ) & & peer - > asUser ( ) - > botInfo & & ! peer - > asUser ( ) - > botInfo - > cantJoinGroups & & ! startToken . isEmpty ( ) ) {
peer - > asUser ( ) - > botInfo - > startGroupToken = startToken ;
2015-12-07 21:09:05 +03:00
Ui : : showLayer ( new ContactsBox ( peer - > asUser ( ) ) ) ;
2016-04-12 01:34:29 +03:00
} else if ( peer - > isUser ( ) & & peer - > asUser ( ) - > botInfo ) {
// Always open bot chats, even from mention links.
Ui : : showPeerHistoryAsync ( peer - > id , ShowAtUnreadMsgId ) ;
2015-06-17 22:43:03 +03:00
} else {
2016-05-19 15:03:51 +03:00
Ui : : showPeerProfile ( peer ) ;
2015-06-17 22:43:03 +03:00
}
2015-03-19 12:18:19 +03:00
} else {
2016-02-18 19:36:33 +03:00
if ( msgId = = ShowAtProfileMsgId | | ! peer - > isChannel ( ) ) { // show specific posts only in channels / supergroups
2016-02-17 19:37:21 +03:00
msgId = ShowAtUnreadMsgId ;
}
2015-09-06 13:17:09 +03:00
if ( peer - > isUser ( ) & & peer - > asUser ( ) - > botInfo ) {
2016-02-17 19:37:21 +03:00
peer - > asUser ( ) - > botInfo - > startToken = startToken ;
2016-04-13 00:31:28 +03:00
if ( peer = = _history - > peer ( ) ) {
_history - > updateControlsVisibility ( ) ;
_history - > resizeEvent ( 0 ) ;
2015-06-19 15:39:33 +03:00
}
}
2016-02-17 19:37:21 +03:00
Ui : : showPeerHistory ( peer - > id , msgId ) ;
2015-03-19 12:18:19 +03:00
}
2014-05-30 12:53:19 +04:00
}
2014-12-05 16:44:27 +03:00
bool MainWidget : : usernameResolveFail ( QString name , const RPCError & error ) {
2016-04-08 14:44:35 +04:00
if ( MTP : : isDefaultHandledError ( error ) ) return false ;
2015-04-04 23:01:34 +03:00
2014-12-05 16:44:27 +03:00
if ( error . code ( ) = = 400 ) {
2015-12-07 21:09:05 +03:00
Ui : : showLayer ( new InformBox ( lng_username_not_found ( lt_user , name ) ) ) ;
2014-12-05 16:44:27 +03:00
}
return true ;
}
2015-04-30 16:53:36 +03:00
void MainWidget : : inviteCheckDone ( QString hash , const MTPChatInvite & invite ) {
switch ( invite . type ( ) ) {
case mtpc_chatInvite : {
2016-04-08 14:44:35 +04:00
const auto & d ( invite . c_chatInvite ( ) ) ;
2015-11-09 12:51:22 +03:00
ConfirmBox * box = new ConfirmBox ( ( ( d . is_channel ( ) & & ! d . is_megagroup ( ) ) ? lng_group_invite_want_join_channel : lng_group_invite_want_join ) ( lt_title , qs ( d . vtitle ) ) , lang ( lng_group_invite_join ) ) ;
2015-04-30 16:53:36 +03:00
_inviteHash = hash ;
connect ( box , SIGNAL ( confirmed ( ) ) , this , SLOT ( onInviteImport ( ) ) ) ;
2015-12-07 21:09:05 +03:00
Ui : : showLayer ( box ) ;
2015-04-30 16:53:36 +03:00
} break ;
case mtpc_chatInviteAlready : {
2016-04-08 14:44:35 +04:00
const auto & d ( invite . c_chatInviteAlready ( ) ) ;
2015-09-03 13:48:40 +03:00
PeerData * chat = App : : feedChats ( MTP_vector < MTPChat > ( 1 , d . vchat ) ) ;
2015-04-30 16:53:36 +03:00
if ( chat ) {
2015-12-13 14:36:08 +03:00
Ui : : showPeerHistory ( chat - > id , ShowAtUnreadMsgId ) ;
2015-04-30 16:53:36 +03:00
}
} break ;
}
}
bool MainWidget : : inviteCheckFail ( const RPCError & error ) {
2016-04-08 14:44:35 +04:00
if ( MTP : : isDefaultHandledError ( error ) ) return false ;
2015-04-30 16:53:36 +03:00
if ( error . code ( ) = = 400 ) {
2015-12-07 21:09:05 +03:00
Ui : : showLayer ( new InformBox ( lang ( lng_group_invite_bad_link ) ) ) ;
2015-04-30 16:53:36 +03:00
}
return true ;
}
void MainWidget : : onInviteImport ( ) {
if ( _inviteHash . isEmpty ( ) ) return ;
2015-10-29 11:26:41 -04:00
MTP : : send ( MTPmessages_ImportChatInvite ( MTP_string ( _inviteHash ) ) , rpcDone ( & MainWidget : : inviteImportDone ) , rpcFail ( & MainWidget : : inviteImportFail ) ) ;
2015-04-30 16:53:36 +03:00
}
void MainWidget : : inviteImportDone ( const MTPUpdates & updates ) {
App : : main ( ) - > sentUpdatesReceived ( updates ) ;
2015-12-07 21:09:05 +03:00
Ui : : hideLayer ( ) ;
2015-04-30 16:53:36 +03:00
const QVector < MTPChat > * v = 0 ;
switch ( updates . type ( ) ) {
case mtpc_updates : v = & updates . c_updates ( ) . vchats . c_vector ( ) . v ; break ;
case mtpc_updatesCombined : v = & updates . c_updatesCombined ( ) . vchats . c_vector ( ) . v ; break ;
2015-09-25 10:47:32 +03:00
default : LOG ( ( " API Error: unexpected update cons %1 (MainWidget::inviteImportDone) " ) . arg ( updates . type ( ) ) ) ; break ;
2015-04-30 16:53:36 +03:00
}
2015-09-21 23:57:42 +03:00
if ( v & & ! v - > isEmpty ( ) ) {
if ( v - > front ( ) . type ( ) = = mtpc_chat ) {
2015-12-13 14:36:08 +03:00
Ui : : showPeerHistory ( peerFromChat ( v - > front ( ) . c_chat ( ) . vid . v ) , ShowAtTheEndMsgId ) ;
2015-09-21 23:57:42 +03:00
} else if ( v - > front ( ) . type ( ) = = mtpc_channel ) {
2015-12-13 14:36:08 +03:00
Ui : : showPeerHistory ( peerFromChannel ( v - > front ( ) . c_channel ( ) . vid . v ) , ShowAtTheEndMsgId ) ;
2015-09-21 23:57:42 +03:00
}
2015-04-30 16:53:36 +03:00
}
}
bool MainWidget : : inviteImportFail ( const RPCError & error ) {
2016-04-08 14:44:35 +04:00
if ( MTP : : isDefaultHandledError ( error ) ) return false ;
2015-04-30 16:53:36 +03:00
if ( error . code ( ) = = 400 ) {
2016-04-08 14:44:35 +04:00
Ui : : showLayer ( new InformBox ( lang ( error . type ( ) = = qstr ( " USERS_TOO_MUCH " ) ? lng_group_invite_no_room : lng_group_invite_bad_link ) ) ) ;
2015-04-30 16:53:36 +03:00
}
return true ;
}
2014-05-30 12:53:19 +04:00
void MainWidget : : startFull ( const MTPVector < MTPUser > & users ) {
2016-04-08 14:44:35 +04:00
const auto & v ( users . c_vector ( ) . v ) ;
2015-10-28 20:16:52 -04:00
if ( v . isEmpty ( ) | | v [ 0 ] . type ( ) ! = mtpc_user | | ! v [ 0 ] . c_user ( ) . is_self ( ) ) { // wtf?..
2016-03-31 18:06:40 +04:00
return App : : logOutDelayed ( ) ;
2014-05-30 12:53:19 +04:00
}
start ( v [ 0 ] ) ;
}
2015-09-21 23:57:42 +03:00
void MainWidget : : applyNotifySetting ( const MTPNotifyPeer & peer , const MTPPeerNotifySettings & settings , History * h ) {
2016-05-12 19:05:20 +03:00
PeerData * updatePeer = nullptr ;
2014-05-30 12:53:19 +04:00
switch ( settings . type ( ) ) {
case mtpc_peerNotifySettingsEmpty :
switch ( peer . type ( ) ) {
case mtpc_notifyAll : globalNotifyAllPtr = EmptyNotifySettings ; break ;
case mtpc_notifyUsers : globalNotifyUsersPtr = EmptyNotifySettings ; break ;
case mtpc_notifyChats : globalNotifyChatsPtr = EmptyNotifySettings ; break ;
case mtpc_notifyPeer : {
2015-12-02 20:17:53 +03:00
updatePeer = App : : peerLoaded ( peerFromMTP ( peer . c_notifyPeer ( ) . vpeer ) ) ;
if ( updatePeer & & updatePeer - > notify ! = EmptyNotifySettings ) {
if ( updatePeer - > notify ! = UnknownNotifySettings ) {
delete updatePeer - > notify ;
2014-05-30 12:53:19 +04:00
}
2015-12-02 20:17:53 +03:00
updatePeer - > notify = EmptyNotifySettings ;
App : : unregMuted ( updatePeer ) ;
if ( ! h ) h = App : : history ( updatePeer - > id ) ;
2015-04-30 16:53:36 +03:00
h - > setMute ( false ) ;
2014-05-30 12:53:19 +04:00
}
} break ;
}
break ;
case mtpc_peerNotifySettings : {
2016-04-08 14:44:35 +04:00
const auto & d ( settings . c_peerNotifySettings ( ) ) ;
2014-05-30 12:53:19 +04:00
NotifySettingsPtr setTo = UnknownNotifySettings ;
switch ( peer . type ( ) ) {
case mtpc_notifyAll : setTo = globalNotifyAllPtr = & globalNotifyAll ; break ;
case mtpc_notifyUsers : setTo = globalNotifyUsersPtr = & globalNotifyUsers ; break ;
case mtpc_notifyChats : setTo = globalNotifyChatsPtr = & globalNotifyChats ; break ;
case mtpc_notifyPeer : {
2015-12-02 20:17:53 +03:00
updatePeer = App : : peerLoaded ( peerFromMTP ( peer . c_notifyPeer ( ) . vpeer ) ) ;
if ( ! updatePeer ) break ;
2014-05-30 12:53:19 +04:00
2015-12-02 20:17:53 +03:00
if ( updatePeer - > notify = = UnknownNotifySettings | | updatePeer - > notify = = EmptyNotifySettings ) {
updatePeer - > notify = new NotifySettings ( ) ;
2014-05-30 12:53:19 +04:00
}
2015-12-02 20:17:53 +03:00
setTo = updatePeer - > notify ;
2014-05-30 12:53:19 +04:00
} break ;
}
if ( setTo = = UnknownNotifySettings ) break ;
2016-02-22 14:15:24 +03:00
setTo - > flags = d . vflags . v ;
2014-05-30 12:53:19 +04:00
setTo - > mute = d . vmute_until . v ;
setTo - > sound = d . vsound . c_string ( ) . v ;
2015-12-02 20:17:53 +03:00
if ( updatePeer ) {
if ( ! h ) h = App : : history ( updatePeer - > id ) ;
2015-04-30 16:53:36 +03:00
int32 changeIn = 0 ;
if ( isNotifyMuted ( setTo , & changeIn ) ) {
2015-09-21 23:57:42 +03:00
App : : wnd ( ) - > notifyClear ( h ) ;
h - > setMute ( true ) ;
2015-12-02 20:17:53 +03:00
App : : regMuted ( updatePeer , changeIn ) ;
2014-05-30 12:53:19 +04:00
} else {
2015-09-21 23:57:42 +03:00
h - > setMute ( false ) ;
}
2014-05-30 12:53:19 +04:00
}
} break ;
}
2015-12-02 20:17:53 +03:00
if ( updatePeer ) {
2016-04-13 00:31:28 +03:00
if ( _history - > peer ( ) = = updatePeer ) {
_history - > updateNotifySettings ( ) ;
2015-12-02 20:17:53 +03:00
}
2016-04-13 00:31:28 +03:00
_dialogs - > updateNotifySettings ( updatePeer ) ;
2016-05-12 19:05:20 +03:00
//if (_profile && _profile->peer() == updatePeer) { TODO
// _profile->updateNotifySettings();
//}
2014-05-30 12:53:19 +04:00
}
}
void MainWidget : : gotNotifySetting ( MTPInputNotifyPeer peer , const MTPPeerNotifySettings & settings ) {
switch ( peer . type ( ) ) {
case mtpc_inputNotifyAll : applyNotifySetting ( MTP_notifyAll ( ) , settings ) ; break ;
case mtpc_inputNotifyUsers : applyNotifySetting ( MTP_notifyUsers ( ) , settings ) ; break ;
case mtpc_inputNotifyChats : applyNotifySetting ( MTP_notifyChats ( ) , settings ) ; break ;
case mtpc_inputNotifyPeer :
switch ( peer . c_inputNotifyPeer ( ) . vpeer . type ( ) ) {
case mtpc_inputPeerEmpty : applyNotifySetting ( MTP_notifyPeer ( MTP_peerUser ( MTP_int ( 0 ) ) ) , settings ) ; break ;
case mtpc_inputPeerSelf : applyNotifySetting ( MTP_notifyPeer ( MTP_peerUser ( MTP_int ( MTP : : authedId ( ) ) ) ) , settings ) ; break ;
2015-08-12 21:01:32 +03:00
case mtpc_inputPeerUser : applyNotifySetting ( MTP_notifyPeer ( MTP_peerUser ( peer . c_inputNotifyPeer ( ) . vpeer . c_inputPeerUser ( ) . vuser_id ) ) , settings ) ; break ;
2014-05-30 12:53:19 +04:00
case mtpc_inputPeerChat : applyNotifySetting ( MTP_notifyPeer ( MTP_peerChat ( peer . c_inputNotifyPeer ( ) . vpeer . c_inputPeerChat ( ) . vchat_id ) ) , settings ) ; break ;
2015-09-21 23:57:42 +03:00
case mtpc_inputPeerChannel : applyNotifySetting ( MTP_notifyPeer ( MTP_peerChannel ( peer . c_inputNotifyPeer ( ) . vpeer . c_inputPeerChannel ( ) . vchannel_id ) ) , settings ) ; break ;
2014-05-30 12:53:19 +04:00
}
break ;
}
2014-07-06 07:32:21 +04:00
App : : wnd ( ) - > notifySettingGot ( ) ;
2014-05-30 12:53:19 +04:00
}
2015-04-04 23:01:34 +03:00
bool MainWidget : : failNotifySetting ( MTPInputNotifyPeer peer , const RPCError & error ) {
2016-04-08 14:44:35 +04:00
if ( MTP : : isDefaultHandledError ( error ) ) return false ;
2015-04-04 23:01:34 +03:00
2014-05-30 12:53:19 +04:00
gotNotifySetting ( peer , MTP_peerNotifySettingsEmpty ( ) ) ;
return true ;
}
2016-02-25 19:19:54 +03:00
void MainWidget : : updateNotifySetting ( PeerData * peer , NotifySettingStatus notify , SilentNotifiesStatus silent ) {
if ( notify = = NotifySettingDontChange & & silent = = SilentNotifiesDontChange ) return ;
2014-05-30 12:53:19 +04:00
updateNotifySettingPeers . insert ( peer ) ;
2015-04-30 16:53:36 +03:00
int32 muteFor = 86400 * 365 ;
2014-05-30 12:53:19 +04:00
if ( peer - > notify = = EmptyNotifySettings ) {
2016-02-25 19:19:54 +03:00
if ( notify = = NotifySettingSetMuted | | silent = = SilentNotifiesSetSilent ) {
2014-05-30 12:53:19 +04:00
peer - > notify = new NotifySettings ( ) ;
}
2016-02-25 19:19:54 +03:00
} else if ( peer - > notify = = UnknownNotifySettings ) {
peer - > notify = new NotifySettings ( ) ;
}
if ( peer - > notify ! = EmptyNotifySettings & & peer - > notify ! = UnknownNotifySettings ) {
if ( notify ! = NotifySettingDontChange ) {
peer - > notify - > sound = ( notify = = NotifySettingSetMuted ) ? " " : " default " ;
peer - > notify - > mute = ( notify = = NotifySettingSetMuted ) ? ( unixtime ( ) + muteFor ) : 0 ;
}
if ( silent = = SilentNotifiesSetSilent ) {
2016-03-19 19:55:15 +03:00
peer - > notify - > flags | = MTPDpeerNotifySettings : : Flag : : f_silent ;
2016-02-25 19:19:54 +03:00
} else if ( silent = = SilentNotifiesSetNotify ) {
2016-03-19 19:55:15 +03:00
peer - > notify - > flags & = ~ MTPDpeerNotifySettings : : Flag : : f_silent ;
2014-05-30 12:53:19 +04:00
}
2015-04-30 16:53:36 +03:00
}
2016-02-25 19:19:54 +03:00
if ( notify ! = NotifySettingDontChange ) {
if ( notify = = NotifySettingSetMuted ) {
App : : regMuted ( peer , muteFor + 1 ) ;
} else {
App : : unregMuted ( peer ) ;
}
App : : history ( peer - > id ) - > setMute ( notify = = NotifySettingSetMuted ) ;
2014-05-30 12:53:19 +04:00
}
2016-04-13 00:31:28 +03:00
if ( _history - > peer ( ) = = peer ) _history - > updateNotifySettings ( ) ;
2014-05-30 12:53:19 +04:00
updateNotifySettingTimer . start ( NotifySettingSaveTimeout ) ;
}
2015-01-02 17:55:24 +03:00
void MainWidget : : incrementSticker ( DocumentData * sticker ) {
2015-07-01 00:07:05 +03:00
if ( ! sticker | | ! sticker - > sticker ( ) ) return ;
2015-05-19 18:46:45 +03:00
RecentStickerPack & recent ( cGetRecentStickers ( ) ) ;
2015-01-02 17:55:24 +03:00
RecentStickerPack : : iterator i = recent . begin ( ) , e = recent . end ( ) ;
for ( ; i ! = e ; + + i ) {
if ( i - > first = = sticker ) {
2016-02-25 20:23:42 +03:00
i - > second = recent . begin ( ) - > second ; // throw to the first place
//++i->second;
//if (i->second > 0x8000) {
// for (RecentStickerPack::iterator j = recent.begin(); j != e; ++j) {
// if (j->second > 1) {
// j->second /= 2;
// } else {
// j->second = 1;
// }
// }
//}
2015-01-02 17:55:24 +03:00
for ( ; i ! = recent . begin ( ) ; - - i ) {
2015-05-19 18:46:45 +03:00
if ( ( i - 1 ) - > second > i - > second ) {
2015-01-02 17:55:24 +03:00
break ;
}
qSwap ( * i , * ( i - 1 ) ) ;
}
break ;
}
}
if ( i = = e ) {
2015-05-19 18:46:45 +03:00
while ( recent . size ( ) > = StickerPanPerRow * StickerPanRowsPerPage ) recent . pop_back ( ) ;
2016-02-25 20:23:42 +03:00
recent . push_front ( qMakePair ( sticker , recent . isEmpty ( ) ? 1 : recent . begin ( ) - > second ) ) ;
//recent.push_back(qMakePair(sticker, 1));
//for (i = recent.end() - 1; i != recent.begin(); --i) {
// if ((i - 1)->second > i->second) {
// break;
// }
// qSwap(*i, *(i - 1));
//}
2015-01-02 17:55:24 +03:00
}
2015-05-19 18:46:45 +03:00
Local : : writeUserSettings ( ) ;
bool found = false ;
uint64 setId = 0 ;
QString setName ;
2015-07-01 00:07:05 +03:00
switch ( sticker - > sticker ( ) - > set . type ( ) ) {
case mtpc_inputStickerSetID : setId = sticker - > sticker ( ) - > set . c_inputStickerSetID ( ) . vid . v ; break ;
case mtpc_inputStickerSetShortName : setName = qs ( sticker - > sticker ( ) - > set . c_inputStickerSetShortName ( ) . vshort_name ) . toLower ( ) . trimmed ( ) ; break ;
2015-05-19 18:46:45 +03:00
}
2016-03-19 19:55:15 +03:00
Stickers : : Sets & sets ( Global : : RefStickerSets ( ) ) ;
for ( auto i = sets . cbegin ( ) ; i ! = sets . cend ( ) ; + + i ) {
if ( i - > id = = Stickers : : CustomSetId | | i - > id = = Stickers : : DefaultSetId | | ( setId & & i - > id = = setId ) | | ( ! setName . isEmpty ( ) & & i - > shortName . toLower ( ) . trimmed ( ) = = setName ) ) {
2015-05-19 18:46:45 +03:00
for ( int32 j = 0 , l = i - > stickers . size ( ) ; j < l ; + + j ) {
if ( i - > stickers . at ( j ) = = sticker ) {
found = true ;
break ;
}
}
if ( found ) break ;
}
}
if ( ! found ) {
2016-03-19 19:55:15 +03:00
Stickers : : Sets : : iterator it = sets . find ( Stickers : : CustomSetId ) ;
2015-05-19 18:46:45 +03:00
if ( it = = sets . cend ( ) ) {
2016-03-19 19:55:15 +03:00
it = sets . insert ( Stickers : : CustomSetId , Stickers : : Set ( Stickers : : CustomSetId , 0 , lang ( lng_custom_stickers ) , QString ( ) , 0 , 0 , 0 ) ) ;
2015-05-19 18:46:45 +03:00
}
it - > stickers . push_back ( sticker ) ;
2015-06-28 15:37:10 +03:00
+ + it - > count ;
2015-05-19 18:46:45 +03:00
Local : : writeStickers ( ) ;
}
2016-04-13 00:31:28 +03:00
_history - > updateRecentStickers ( ) ;
2015-01-02 17:55:24 +03:00
}
2014-05-30 12:53:19 +04:00
void MainWidget : : activate ( ) {
2015-10-17 16:52:26 +02:00
if ( _a_show . animating ( ) ) return ;
2016-05-19 15:03:51 +03:00
if ( ! _wideSection & & ! _overview ) {
2015-07-17 22:17:37 +03:00
if ( _hider ) {
if ( _hider - > wasOffered ( ) ) {
_hider - > setFocus ( ) ;
2014-05-30 12:53:19 +04:00
} else {
2016-04-13 00:31:28 +03:00
_dialogs - > activate ( ) ;
2014-05-30 12:53:19 +04:00
}
2015-12-07 21:09:05 +03:00
} else if ( App : : wnd ( ) & & ! Ui : : isLayerShown ( ) ) {
2014-07-18 14:37:34 +04:00
if ( ! cSendPaths ( ) . isEmpty ( ) ) {
2014-12-12 19:27:03 +03:00
forwardLayer ( - 1 ) ;
2016-04-13 00:31:28 +03:00
} else if ( _history - > peer ( ) ) {
_history - > activate ( ) ;
2014-07-18 14:37:34 +04:00
} else {
2016-04-13 00:31:28 +03:00
_dialogs - > activate ( ) ;
2014-07-18 14:37:34 +04:00
}
2014-05-30 12:53:19 +04:00
}
}
App : : wnd ( ) - > fixOrder ( ) ;
}
void MainWidget : : destroyData ( ) {
2016-04-13 00:31:28 +03:00
_history - > destroyData ( ) ;
_dialogs - > destroyData ( ) ;
2014-05-30 12:53:19 +04:00
}
void MainWidget : : updateOnlineDisplayIn ( int32 msecs ) {
2015-01-26 16:04:41 +03:00
_onlineUpdater . start ( msecs ) ;
2014-05-30 12:53:19 +04:00
}
bool MainWidget : : isActive ( ) const {
2015-10-17 16:52:26 +02:00
return ! _isIdle & & isVisible ( ) & & ! _a_show . animating ( ) ;
2014-05-30 12:53:19 +04:00
}
bool MainWidget : : historyIsActive ( ) const {
2016-05-19 15:03:51 +03:00
return isActive ( ) & & ! _wideSection & & ! _overview & & _history - > isActive ( ) ;
2014-05-30 12:53:19 +04:00
}
2015-01-26 16:04:41 +03:00
bool MainWidget : : lastWasOnline ( ) const {
return _lastWasOnline ;
}
uint64 MainWidget : : lastSetOnline ( ) const {
return _lastSetOnline ;
}
2014-05-30 12:53:19 +04:00
int32 MainWidget : : dlgsWidth ( ) const {
2016-04-13 00:31:28 +03:00
return _dialogs - > width ( ) ;
2014-05-30 12:53:19 +04:00
}
MainWidget : : ~ MainWidget ( ) {
2016-04-13 00:31:28 +03:00
if ( App : : main ( ) = = this ) _history - > showHistory ( 0 , 0 ) ;
2015-02-03 18:02:46 +03:00
2015-07-17 22:17:37 +03:00
delete _hider ;
2014-05-30 12:53:19 +04:00
MTP : : clearGlobalHandlers ( ) ;
2016-04-13 00:31:28 +03:00
2014-05-30 12:53:19 +04:00
if ( App : : wnd ( ) ) App : : wnd ( ) - > noMain ( this ) ;
}
2015-01-26 16:04:41 +03:00
void MainWidget : : updateOnline ( bool gotOtherOffline ) {
2015-03-02 15:34:16 +03:00
if ( this ! = App : : main ( ) ) return ;
App : : wnd ( ) - > checkAutoLock ( ) ;
2015-01-26 16:04:41 +03:00
bool isOnline = App : : wnd ( ) - > isActive ( ) ;
2016-02-18 19:36:33 +03:00
int updateIn = Global : : OnlineUpdatePeriod ( ) ;
2015-01-26 16:04:41 +03:00
if ( isOnline ) {
uint64 idle = psIdleTime ( ) ;
2016-02-18 19:36:33 +03:00
if ( idle > = uint64 ( Global : : OfflineIdleTimeout ( ) ) ) {
2015-01-26 16:04:41 +03:00
isOnline = false ;
if ( ! _isIdle ) {
_isIdle = true ;
_idleFinishTimer . start ( 900 ) ;
}
} else {
2016-02-18 19:36:33 +03:00
updateIn = qMin ( updateIn , int ( Global : : OfflineIdleTimeout ( ) - idle ) ) ;
2015-01-26 16:04:41 +03:00
}
2014-05-30 12:53:19 +04:00
}
2015-01-26 16:04:41 +03:00
uint64 ms = getms ( true ) ;
2016-02-18 19:36:33 +03:00
if ( isOnline ! = _lastWasOnline | | ( isOnline & & _lastSetOnline + Global : : OnlineUpdatePeriod ( ) < = ms ) | | ( isOnline & & gotOtherOffline ) ) {
2015-01-26 16:04:41 +03:00
if ( _onlineRequest ) {
MTP : : cancel ( _onlineRequest ) ;
_onlineRequest = 0 ;
}
_lastWasOnline = isOnline ;
_lastSetOnline = ms ;
_onlineRequest = MTP : : send ( MTPaccount_UpdateStatus ( MTP_bool ( ! isOnline ) ) ) ;
2016-02-18 19:36:33 +03:00
if ( App : : self ( ) ) App : : self ( ) - > onlineTill = unixtime ( ) + ( isOnline ? ( Global : : OnlineUpdatePeriod ( ) / 1000 ) : - 1 ) ;
2015-01-26 16:04:41 +03:00
_lastSetOnline = getms ( true ) ;
updateOnlineDisplay ( ) ;
} else if ( isOnline ) {
2016-02-18 19:36:33 +03:00
updateIn = qMin ( updateIn , int ( _lastSetOnline + Global : : OnlineUpdatePeriod ( ) - ms ) ) ;
2014-05-30 12:53:19 +04:00
}
2015-01-26 16:04:41 +03:00
_onlineTimer . start ( updateIn ) ;
2014-05-30 12:53:19 +04:00
}
2015-01-26 16:04:41 +03:00
void MainWidget : : checkIdleFinish ( ) {
2015-03-02 15:34:16 +03:00
if ( this ! = App : : main ( ) ) return ;
2016-02-18 19:36:33 +03:00
if ( psIdleTime ( ) < uint64 ( Global : : OfflineIdleTimeout ( ) ) ) {
2015-01-26 16:04:41 +03:00
_idleFinishTimer . stop ( ) ;
_isIdle = false ;
updateOnline ( ) ;
if ( App : : wnd ( ) ) App : : wnd ( ) - > checkHistoryActivation ( ) ;
} else {
_idleFinishTimer . start ( 900 ) ;
}
2014-05-30 12:53:19 +04:00
}
void MainWidget : : updateReceived ( const mtpPrime * from , const mtpPrime * end ) {
if ( end < = from | | ! MTP : : authedId ( ) ) return ;
2015-03-02 15:34:16 +03:00
App : : wnd ( ) - > checkAutoLock ( ) ;
2015-12-31 23:27:21 +08:00
2014-06-14 23:32:11 +04:00
if ( mtpTypeId ( * from ) = = mtpc_new_session_created ) {
2014-05-30 12:53:19 +04:00
MTPNewSession newSession ( from , end ) ;
updSeq = 0 ;
2015-04-30 16:53:36 +03:00
MTP_LOG ( 0 , ( " getDifference { after new_session_created }%1 " ) . arg ( cTestMode ( ) ? " TESTMODE " : " " ) ) ;
2014-05-30 12:53:19 +04:00
return getDifference ( ) ;
} else {
try {
MTPUpdates updates ( from , end ) ;
2014-11-12 23:30:26 +03:00
_lastUpdateTime = getms ( true ) ;
2014-05-30 12:53:19 +04:00
noUpdatesTimer . start ( NoUpdatesTimeout ) ;
2015-09-21 23:57:42 +03:00
if ( ! _ptsWaiter . requesting ( ) ) {
feedUpdates ( updates ) ;
}
2016-05-25 15:09:05 +03:00
Notify : : peerUpdatedSendDelayed ( ) ;
2016-03-20 11:16:35 +03:00
} catch ( mtpErrorUnexpected & ) { // just some other type
2014-11-05 20:43:32 +03:00
}
}
update ( ) ;
}
2014-05-30 12:53:19 +04:00
2016-05-09 13:07:25 +03:00
namespace {
bool fwdInfoDataLoaded ( const MTPMessageFwdHeader & header ) {
if ( header . type ( ) ! = mtpc_messageFwdHeader ) {
return true ;
}
auto & info = header . c_messageFwdHeader ( ) ;
if ( info . has_channel_id ( ) ) {
if ( ! App : : channelLoaded ( peerFromChannel ( info . vchannel_id ) ) ) {
return false ;
}
if ( info . has_from_id ( ) & & ! App : : user ( peerFromUser ( info . vfrom_id ) , PeerData : : MinimalLoaded ) ) {
return false ;
}
} else {
if ( info . has_from_id ( ) & & ! App : : userLoaded ( peerFromUser ( info . vfrom_id ) ) ) {
return false ;
}
}
return true ;
}
bool mentionUsersLoaded ( const MTPVector < MTPMessageEntity > & entities ) {
for_const ( auto & entity , entities . c_vector ( ) . v ) {
auto type = entity . type ( ) ;
if ( type = = mtpc_messageEntityMentionName ) {
if ( ! App : : userLoaded ( peerFromUser ( entity . c_messageEntityMentionName ( ) . vuser_id ) ) ) {
return false ;
}
} else if ( type = = mtpc_inputMessageEntityMentionName ) {
auto & inputUser = entity . c_inputMessageEntityMentionName ( ) . vuser_id ;
if ( inputUser . type ( ) = = mtpc_inputUser ) {
if ( ! App : : userLoaded ( peerFromUser ( inputUser . c_inputUser ( ) . vuser_id ) ) ) {
return false ;
}
}
}
}
return true ;
}
enum class DataIsLoadedResult {
NotLoaded = 0 ,
FromNotLoaded = 1 ,
MentionNotLoaded = 2 ,
Ok = 3 ,
} ;
DataIsLoadedResult allDataLoadedForMessage ( const MTPMessage & msg ) {
switch ( msg . type ( ) ) {
case mtpc_message : {
const MTPDmessage & d ( msg . c_message ( ) ) ;
if ( ! d . is_post ( ) & & d . has_from_id ( ) ) {
if ( ! App : : userLoaded ( peerFromUser ( d . vfrom_id ) ) ) {
return DataIsLoadedResult : : FromNotLoaded ;
}
}
if ( d . has_via_bot_id ( ) ) {
if ( ! App : : userLoaded ( peerFromUser ( d . vvia_bot_id ) ) ) {
return DataIsLoadedResult : : NotLoaded ;
}
}
if ( d . has_fwd_from ( ) & & ! fwdInfoDataLoaded ( d . vfwd_from ) ) {
return DataIsLoadedResult : : NotLoaded ;
}
if ( d . has_entities ( ) & & ! mentionUsersLoaded ( d . ventities ) ) {
return DataIsLoadedResult : : MentionNotLoaded ;
}
} break ;
case mtpc_messageService : {
const MTPDmessageService & d ( msg . c_messageService ( ) ) ;
if ( ! d . is_post ( ) & & d . has_from_id ( ) ) {
if ( ! App : : userLoaded ( peerFromUser ( d . vfrom_id ) ) ) {
return DataIsLoadedResult : : FromNotLoaded ;
}
}
switch ( d . vaction . type ( ) ) {
case mtpc_messageActionChatAddUser : {
for_const ( const MTPint & userId , d . vaction . c_messageActionChatAddUser ( ) . vusers . c_vector ( ) . v ) {
if ( ! App : : userLoaded ( peerFromUser ( userId ) ) ) {
return DataIsLoadedResult : : NotLoaded ;
}
}
} break ;
case mtpc_messageActionChatJoinedByLink : {
if ( ! App : : userLoaded ( peerFromUser ( d . vaction . c_messageActionChatJoinedByLink ( ) . vinviter_id ) ) ) {
return DataIsLoadedResult : : NotLoaded ;
}
} break ;
case mtpc_messageActionChatDeleteUser : {
if ( ! App : : userLoaded ( peerFromUser ( d . vaction . c_messageActionChatDeleteUser ( ) . vuser_id ) ) ) {
return DataIsLoadedResult : : NotLoaded ;
}
} break ;
}
} break ;
}
return DataIsLoadedResult : : Ok ;
}
} // namespace
2015-09-21 23:57:42 +03:00
void MainWidget : : feedUpdates ( const MTPUpdates & updates , uint64 randomId ) {
2014-11-05 20:43:32 +03:00
switch ( updates . type ( ) ) {
case mtpc_updates : {
2016-04-08 14:44:35 +04:00
const auto & d ( updates . c_updates ( ) ) ;
2014-11-05 20:43:32 +03:00
if ( d . vseq . v ) {
if ( d . vseq . v < = updSeq ) return ;
if ( d . vseq . v > updSeq + 1 ) {
_bySeqUpdates . insert ( d . vseq . v , updates ) ;
2015-03-13 16:01:25 +03:00
return _bySeqTimer . start ( WaitForSkippedTimeout ) ;
2014-11-05 20:43:32 +03:00
}
}
2014-05-30 12:53:19 +04:00
2016-05-25 15:09:05 +03:00
App : : feedUsersDelayed ( d . vusers ) ;
App : : feedChatsDelayed ( d . vchats ) ;
2015-09-21 23:57:42 +03:00
feedUpdateVector ( d . vupdates ) ;
2014-05-30 12:53:19 +04:00
2015-03-13 16:01:25 +03:00
updSetState ( 0 , d . vdate . v , updQts , d . vseq . v ) ;
2014-11-05 20:43:32 +03:00
} break ;
2014-05-30 12:53:19 +04:00
2014-11-05 20:43:32 +03:00
case mtpc_updatesCombined : {
2016-04-08 14:44:35 +04:00
const auto & d ( updates . c_updatesCombined ( ) ) ;
2014-11-05 20:43:32 +03:00
if ( d . vseq_start . v ) {
if ( d . vseq_start . v < = updSeq ) return ;
if ( d . vseq_start . v > updSeq + 1 ) {
_bySeqUpdates . insert ( d . vseq_start . v , updates ) ;
2015-03-13 16:01:25 +03:00
return _bySeqTimer . start ( WaitForSkippedTimeout ) ;
2014-11-05 20:43:32 +03:00
}
}
2014-05-30 12:53:19 +04:00
2016-05-25 15:09:05 +03:00
App : : feedUsersDelayed ( d . vusers ) ;
App : : feedChatsDelayed ( d . vchats ) ;
2015-09-21 23:57:42 +03:00
feedUpdateVector ( d . vupdates ) ;
2014-05-30 12:53:19 +04:00
2015-03-13 16:01:25 +03:00
updSetState ( 0 , d . vdate . v , updQts , d . vseq . v ) ;
2014-11-05 20:43:32 +03:00
} break ;
2014-05-30 12:53:19 +04:00
2014-11-05 20:43:32 +03:00
case mtpc_updateShort : {
2016-04-08 14:44:35 +04:00
const auto & d ( updates . c_updateShort ( ) ) ;
2014-05-30 12:53:19 +04:00
2014-11-05 20:43:32 +03:00
feedUpdate ( d . vupdate ) ;
2014-05-30 12:53:19 +04:00
2015-03-13 16:01:25 +03:00
updSetState ( 0 , d . vdate . v , updQts , updSeq ) ;
2014-11-05 20:43:32 +03:00
} break ;
2014-05-30 12:53:19 +04:00
2014-11-05 20:43:32 +03:00
case mtpc_updateShortMessage : {
2016-04-08 14:44:35 +04:00
const auto & d ( updates . c_updateShortMessage ( ) ) ;
2016-05-09 13:07:25 +03:00
if ( ! App : : userLoaded ( d . vuser_id . v )
| | ( d . has_via_bot_id ( ) & & ! App : : userLoaded ( d . vvia_bot_id . v ) )
| | ( d . has_entities ( ) & & ! mentionUsersLoaded ( d . ventities ) )
| | ( d . has_fwd_from ( ) & & ! fwdInfoDataLoaded ( d . vfwd_from ) ) ) {
2015-04-30 16:53:36 +03:00
MTP_LOG ( 0 , ( " getDifference { good - getting user for updateShortMessage }%1 " ) . arg ( cTestMode ( ) ? " TESTMODE " : " " ) ) ;
2015-03-20 00:56:13 +03:00
return getDifference ( ) ;
}
2015-09-13 11:41:27 +03:00
if ( ! ptsUpdated ( d . vpts . v , d . vpts_count . v , updates ) ) {
2015-03-13 16:01:25 +03:00
return ;
2014-11-05 20:43:32 +03:00
}
2015-09-20 12:54:22 +03:00
// update before applying skipped
2016-03-19 19:55:15 +03:00
MTPDmessage : : Flags flags = mtpCastFlags ( d . vflags . v ) | MTPDmessage : : Flag : : f_from_id ;
HistoryItem * item = App : : histories ( ) . addNewMessage ( MTP_message ( MTP_flags ( flags ) , d . vid , d . is_out ( ) ? MTP_int ( MTP : : authedId ( ) ) : d . vuser_id , MTP_peerUser ( d . is_out ( ) ? d . vuser_id : MTP_int ( MTP : : authedId ( ) ) ) , d . vfwd_from , d . vvia_bot_id , d . vreply_to_msg_id , d . vdate , d . vmessage , MTP_messageMediaEmpty ( ) , MTPnullMarkup , d . has_entities ( ) ? d . ventities : MTPnullEntities , MTPint ( ) , MTPint ( ) ) , NewMessageUnread ) ;
2014-11-05 20:43:32 +03:00
if ( item ) {
2016-04-13 00:31:28 +03:00
_history - > peerMessagesUpdated ( item - > history ( ) - > peer - > id ) ;
2014-11-05 20:43:32 +03:00
}
2014-05-30 12:53:19 +04:00
2015-09-20 12:54:22 +03:00
ptsApplySkippedUpdates ( ) ;
2015-03-13 16:01:25 +03:00
updSetState ( 0 , d . vdate . v , updQts , updSeq ) ;
2014-11-05 20:43:32 +03:00
} break ;
2014-05-30 12:53:19 +04:00
2014-11-05 20:43:32 +03:00
case mtpc_updateShortChatMessage : {
2016-04-08 14:44:35 +04:00
const auto & d ( updates . c_updateShortChatMessage ( ) ) ;
2015-05-08 16:06:53 +03:00
bool noFrom = ! App : : userLoaded ( d . vfrom_id . v ) ;
2016-05-09 13:07:25 +03:00
if ( ! App : : chatLoaded ( d . vchat_id . v )
| | noFrom
| | ( d . has_via_bot_id ( ) & & ! App : : userLoaded ( d . vvia_bot_id . v ) )
| | ( d . has_entities ( ) & & ! mentionUsersLoaded ( d . ventities ) )
| | ( d . has_fwd_from ( ) & & ! fwdInfoDataLoaded ( d . vfwd_from ) ) ) {
2015-04-30 16:53:36 +03:00
MTP_LOG ( 0 , ( " getDifference { good - getting user for updateShortChatMessage }%1 " ) . arg ( cTestMode ( ) ? " TESTMODE " : " " ) ) ;
2015-10-03 14:33:51 +03:00
if ( noFrom & & App : : api ( ) ) App : : api ( ) - > requestFullPeer ( App : : chatLoaded ( d . vchat_id . v ) ) ;
2015-03-20 00:56:13 +03:00
return getDifference ( ) ;
}
2015-09-13 11:41:27 +03:00
if ( ! ptsUpdated ( d . vpts . v , d . vpts_count . v , updates ) ) {
2015-03-13 16:01:25 +03:00
return ;
2014-05-30 12:53:19 +04:00
}
2015-09-20 12:54:22 +03:00
// update before applying skipped
2016-03-19 19:55:15 +03:00
MTPDmessage : : Flags flags = mtpCastFlags ( d . vflags . v ) | MTPDmessage : : Flag : : f_from_id ;
HistoryItem * item = App : : histories ( ) . addNewMessage ( MTP_message ( MTP_flags ( flags ) , d . vid , d . vfrom_id , MTP_peerChat ( d . vchat_id ) , d . vfwd_from , d . vvia_bot_id , d . vreply_to_msg_id , d . vdate , d . vmessage , MTP_messageMediaEmpty ( ) , MTPnullMarkup , d . has_entities ( ) ? d . ventities : MTPnullEntities , MTPint ( ) , MTPint ( ) ) , NewMessageUnread ) ;
2014-11-05 20:43:32 +03:00
if ( item ) {
2016-04-13 00:31:28 +03:00
_history - > peerMessagesUpdated ( item - > history ( ) - > peer - > id ) ;
2014-11-05 20:43:32 +03:00
}
2015-09-20 12:54:22 +03:00
ptsApplySkippedUpdates ( ) ;
2015-03-13 16:01:25 +03:00
updSetState ( 0 , d . vdate . v , updQts , updSeq ) ;
2014-11-05 20:43:32 +03:00
} break ;
2015-08-30 17:57:21 +03:00
case mtpc_updateShortSentMessage : {
2016-04-08 14:44:35 +04:00
const auto & d ( updates . c_updateShortSentMessage ( ) ) ;
2015-08-30 17:57:21 +03:00
if ( randomId ) {
2015-09-03 13:48:40 +03:00
PeerId peerId = 0 ;
QString text ;
App : : histSentDataByItem ( randomId , peerId , text ) ;
2015-08-30 17:57:21 +03:00
feedUpdate ( MTP_updateMessageID ( d . vid , MTP_long ( randomId ) ) ) ; // ignore real date
2015-09-03 13:48:40 +03:00
if ( peerId ) {
2016-05-06 20:33:48 +03:00
if ( auto item = App : : histItemById ( peerToChannel ( peerId ) , d . vid . v ) ) {
2016-05-09 13:07:25 +03:00
if ( d . has_entities ( ) & & ! mentionUsersLoaded ( d . ventities ) ) {
api ( ) - > requestMessageData ( item - > history ( ) - > peer - > asChannel ( ) , item - > id , nullptr ) ;
}
2016-05-06 20:33:48 +03:00
auto entities = d . has_entities ( ) ? entitiesFromMTP ( d . ventities . c_vector ( ) . v ) : EntitiesInText ( ) ;
item - > setText ( { text , entities } ) ;
2016-04-01 14:23:40 +04:00
item - > updateMedia ( d . has_media ( ) ? ( & d . vmedia ) : nullptr ) ;
2016-01-03 09:43:42 +08:00
item - > addToOverview ( AddToOverviewNew ) ;
2015-09-03 13:48:40 +03:00
}
2015-08-30 17:57:21 +03:00
}
}
2015-12-31 23:27:21 +08:00
2015-09-13 11:41:27 +03:00
if ( ! ptsUpdated ( d . vpts . v , d . vpts_count . v , updates ) ) {
2015-08-30 17:57:21 +03:00
return ;
}
2015-09-20 12:54:22 +03:00
// update before applying skipped
ptsApplySkippedUpdates ( ) ;
2015-08-30 17:57:21 +03:00
updSetState ( 0 , d . vdate . v , updQts , updSeq ) ;
} break ;
2014-11-05 20:43:32 +03:00
case mtpc_updatesTooLong : {
2015-04-30 16:53:36 +03:00
MTP_LOG ( 0 , ( " getDifference { good - updatesTooLong received }%1 " ) . arg ( cTestMode ( ) ? " TESTMODE " : " " ) ) ;
2014-11-05 20:43:32 +03:00
return getDifference ( ) ;
} break ;
2014-05-30 12:53:19 +04:00
}
}
void MainWidget : : feedUpdate ( const MTPUpdate & update ) {
if ( ! MTP : : authedId ( ) ) return ;
switch ( update . type ( ) ) {
case mtpc_updateNewMessage : {
2016-04-08 14:44:35 +04:00
const auto & d ( update . c_updateNewMessage ( ) ) ;
2015-09-20 12:54:22 +03:00
2015-09-13 11:41:27 +03:00
if ( ! ptsUpdated ( d . vpts . v , d . vpts_count . v , update ) ) {
2015-03-13 16:01:25 +03:00
return ;
}
2015-09-20 12:54:22 +03:00
// update before applying skipped
2015-10-15 02:15:28 +02:00
bool needToAdd = true ;
2016-04-13 00:31:28 +03:00
if ( d . vmessage . type ( ) = = mtpc_message ) { // index forwarded messages to links _overview
2015-10-15 02:15:28 +02:00
if ( App : : checkEntitiesAndViewsUpdate ( d . vmessage . c_message ( ) ) ) { // already in blocks
LOG ( ( " Skipping message, because it is already in blocks! " ) ) ;
needToAdd = false ;
}
2015-09-02 00:33:44 +03:00
}
2015-10-15 02:15:28 +02:00
if ( needToAdd ) {
HistoryItem * item = App : : histories ( ) . addNewMessage ( d . vmessage , NewMessageUnread ) ;
if ( item ) {
2016-04-13 00:31:28 +03:00
_history - > peerMessagesUpdated ( item - > history ( ) - > peer - > id ) ;
2015-10-15 02:15:28 +02:00
}
2014-07-04 15:12:54 +04:00
}
2015-09-20 12:54:22 +03:00
ptsApplySkippedUpdates ( ) ;
2014-05-30 12:53:19 +04:00
} break ;
case mtpc_updateMessageID : {
2016-04-08 14:44:35 +04:00
const auto & d ( update . c_updateMessageID ( ) ) ;
2015-09-03 13:48:40 +03:00
FullMsgId msg = App : : histItemByRandom ( d . vrandom_id . v ) ;
if ( msg . msg ) {
2014-05-30 12:53:19 +04:00
HistoryItem * msgRow = App : : histItemById ( msg ) ;
if ( msgRow ) {
2015-12-23 15:55:32 +03:00
if ( App : : histItemById ( msg . channel , d . vid . v ) ) {
2015-11-18 16:11:56 +03:00
History * h = msgRow - > history ( ) ;
2015-09-19 12:13:21 +03:00
bool wasLast = ( h - > lastMsg = = msgRow ) ;
2014-05-30 12:53:19 +04:00
msgRow - > destroy ( ) ;
2015-09-19 12:13:21 +03:00
if ( wasLast & & ! h - > lastMsg ) {
checkPeerHistory ( h - > peer ) ;
}
2016-04-13 00:31:28 +03:00
_history - > peerMessagesUpdated ( ) ;
2015-12-23 15:55:32 +03:00
} else {
App : : historyUnregItem ( msgRow ) ;
if ( App : : wnd ( ) ) App : : wnd ( ) - > changingMsgId ( msgRow , d . vid . v ) ;
msgRow - > setId ( d . vid . v ) ;
if ( msgRow - > history ( ) - > peer - > isSelf ( ) ) {
msgRow - > history ( ) - > unregTyping ( App : : self ( ) ) ;
}
App : : historyRegItem ( msgRow ) ;
2015-12-28 00:37:48 +03:00
Ui : : repaintHistoryItem ( msgRow ) ;
2014-05-30 12:53:19 +04:00
}
}
App : : historyUnregRandom ( d . vrandom_id . v ) ;
}
2015-09-03 13:48:40 +03:00
App : : historyUnregSentData ( d . vrandom_id . v ) ;
2014-05-30 12:53:19 +04:00
} break ;
2015-04-30 16:53:36 +03:00
case mtpc_updateReadMessagesContents : {
2016-04-08 14:44:35 +04:00
const auto & d ( update . c_updateReadMessagesContents ( ) ) ;
2015-09-20 12:54:22 +03:00
2015-09-13 11:41:27 +03:00
if ( ! ptsUpdated ( d . vpts . v , d . vpts_count . v , update ) ) {
2015-03-13 16:01:25 +03:00
return ;
}
2015-09-20 12:54:22 +03:00
// update before applying skipped
2016-04-08 14:44:35 +04:00
const auto & v ( d . vmessages . c_vector ( ) . v ) ;
2015-04-30 16:53:36 +03:00
for ( int32 i = 0 , l = v . size ( ) ; i < l ; + + i ) {
2015-09-03 13:48:40 +03:00
if ( HistoryItem * item = App : : histItemById ( NoChannel , v . at ( i ) . v ) ) {
2015-04-30 16:53:36 +03:00
if ( item - > isMediaUnread ( ) ) {
item - > markMediaRead ( ) ;
2015-12-28 00:37:48 +03:00
Ui : : repaintHistoryItem ( item ) ;
2015-09-03 13:48:40 +03:00
if ( item - > out ( ) & & item - > history ( ) - > peer - > isUser ( ) ) {
2015-06-28 15:37:10 +03:00
item - > history ( ) - > peer - > asUser ( ) - > madeAction ( ) ;
}
2015-04-30 16:53:36 +03:00
}
}
}
2015-09-20 12:54:22 +03:00
ptsApplySkippedUpdates ( ) ;
2015-03-13 16:01:25 +03:00
} break ;
case mtpc_updateReadHistoryInbox : {
2016-04-08 14:44:35 +04:00
const auto & d ( update . c_updateReadHistoryInbox ( ) ) ;
2015-09-20 12:54:22 +03:00
2015-09-13 11:41:27 +03:00
if ( ! ptsUpdated ( d . vpts . v , d . vpts_count . v , update ) ) {
2015-03-13 16:01:25 +03:00
return ;
}
2015-09-20 12:54:22 +03:00
// update before applying skipped
2015-09-03 13:48:40 +03:00
App : : feedInboxRead ( peerFromMTP ( d . vpeer ) , d . vmax_id . v ) ;
2015-09-20 12:54:22 +03:00
ptsApplySkippedUpdates ( ) ;
2015-03-13 16:01:25 +03:00
} break ;
case mtpc_updateReadHistoryOutbox : {
2016-04-08 14:44:35 +04:00
const auto & d ( update . c_updateReadHistoryOutbox ( ) ) ;
2015-09-20 12:54:22 +03:00
2015-09-13 11:41:27 +03:00
if ( ! ptsUpdated ( d . vpts . v , d . vpts_count . v , update ) ) {
2015-03-13 16:01:25 +03:00
return ;
}
2015-09-20 12:54:22 +03:00
// update before applying skipped
2015-09-03 13:48:40 +03:00
PeerId id = peerFromMTP ( d . vpeer ) ;
App : : feedOutboxRead ( id , d . vmax_id . v ) ;
2016-04-13 00:31:28 +03:00
if ( _history - > peer ( ) & & _history - > peer ( ) - > id = = id ) {
_history - > update ( ) ;
2015-10-03 13:09:09 +03:00
}
if ( History * h = App : : historyLoaded ( id ) ) {
2015-10-14 16:11:42 +02:00
if ( h - > lastMsg & & h - > lastMsg - > out ( ) & & h - > lastMsg - > id < = d . vmax_id . v ) {
2015-10-03 13:09:09 +03:00
dlgUpdated ( h , h - > lastMsg - > id ) ;
}
2016-02-28 14:58:30 +03:00
h - > updateChatListEntry ( ) ;
2015-10-03 13:09:09 +03:00
}
2015-09-20 12:54:22 +03:00
ptsApplySkippedUpdates ( ) ;
2014-05-30 12:53:19 +04:00
} break ;
2015-04-02 13:33:19 +03:00
case mtpc_updateWebPage : {
2016-04-08 14:44:35 +04:00
const auto & d ( update . c_updateWebPage ( ) ) ;
2015-09-20 12:54:22 +03:00
2015-09-13 11:41:27 +03:00
if ( ! ptsUpdated ( d . vpts . v , d . vpts_count . v , update ) ) {
2015-09-09 10:46:31 +03:00
return ;
}
2015-09-20 12:54:22 +03:00
// update before applying skipped
2015-04-08 02:03:32 +03:00
App : : feedWebPage ( d . vwebpage ) ;
2016-04-13 00:31:28 +03:00
_history - > updatePreview ( ) ;
2015-04-30 16:53:36 +03:00
webPagesUpdate ( ) ;
2015-09-20 12:54:22 +03:00
ptsApplySkippedUpdates ( ) ;
2015-04-02 13:33:19 +03:00
} break ;
2014-05-30 12:53:19 +04:00
case mtpc_updateDeleteMessages : {
2016-04-08 14:44:35 +04:00
const auto & d ( update . c_updateDeleteMessages ( ) ) ;
2015-09-20 12:54:22 +03:00
2015-09-13 11:41:27 +03:00
if ( ! ptsUpdated ( d . vpts . v , d . vpts_count . v , update ) ) {
2015-03-13 16:01:25 +03:00
return ;
}
2015-09-20 12:54:22 +03:00
// update before applying skipped
2015-09-03 13:48:40 +03:00
App : : feedWereDeleted ( NoChannel , d . vmessages . c_vector ( ) . v ) ;
2016-04-13 00:31:28 +03:00
_history - > peerMessagesUpdated ( ) ;
2015-09-20 12:54:22 +03:00
ptsApplySkippedUpdates ( ) ;
2014-05-30 12:53:19 +04:00
} break ;
case mtpc_updateUserTyping : {
2016-04-08 14:44:35 +04:00
const auto & d ( update . c_updateUserTyping ( ) ) ;
2015-09-03 13:48:40 +03:00
History * history = App : : historyLoaded ( peerFromUser ( d . vuser_id ) ) ;
2014-05-30 12:53:19 +04:00
UserData * user = App : : userLoaded ( d . vuser_id . v ) ;
if ( history & & user ) {
2015-08-01 11:33:00 +03:00
App : : histories ( ) . regSendAction ( history , user , d . vaction ) ;
2014-05-30 12:53:19 +04:00
}
} break ;
case mtpc_updateChatUserTyping : {
2016-04-08 14:44:35 +04:00
const auto & d ( update . c_updateChatUserTyping ( ) ) ;
2015-09-08 16:34:22 +03:00
History * history = 0 ;
2016-03-25 14:29:45 +03:00
if ( PeerData * chat = App : : chatLoaded ( d . vchat_id . v ) ) {
2015-09-08 16:34:22 +03:00
history = App : : historyLoaded ( chat - > id ) ;
2016-03-25 14:29:45 +03:00
} else if ( PeerData * channel = App : : channelLoaded ( d . vchat_id . v ) ) {
2015-09-08 16:34:22 +03:00
history = App : : historyLoaded ( channel - > id ) ;
}
2014-05-30 12:53:19 +04:00
UserData * user = ( d . vuser_id . v = = MTP : : authedId ( ) ) ? 0 : App : : userLoaded ( d . vuser_id . v ) ;
if ( history & & user ) {
2015-08-01 11:33:00 +03:00
App : : histories ( ) . regSendAction ( history , user , d . vaction ) ;
2014-05-30 12:53:19 +04:00
}
} break ;
case mtpc_updateChatParticipants : {
2015-10-29 15:10:49 -04:00
App : : feedParticipants ( update . c_updateChatParticipants ( ) . vparticipants , true , false ) ;
2014-05-30 12:53:19 +04:00
} break ;
case mtpc_updateChatParticipantAdd : {
2015-10-29 15:10:49 -04:00
App : : feedParticipantAdd ( update . c_updateChatParticipantAdd ( ) , false ) ;
2014-05-30 12:53:19 +04:00
} break ;
case mtpc_updateChatParticipantDelete : {
2015-10-29 15:10:49 -04:00
App : : feedParticipantDelete ( update . c_updateChatParticipantDelete ( ) , false ) ;
} break ;
case mtpc_updateChatAdmins : {
App : : feedChatAdmins ( update . c_updateChatAdmins ( ) , false ) ;
} break ;
case mtpc_updateChatParticipantAdmin : {
App : : feedParticipantAdmin ( update . c_updateChatParticipantAdmin ( ) , false ) ;
2014-05-30 12:53:19 +04:00
} break ;
case mtpc_updateUserStatus : {
2016-04-08 14:44:35 +04:00
const auto & d ( update . c_updateUserStatus ( ) ) ;
2015-01-26 16:04:41 +03:00
UserData * user = App : : userLoaded ( d . vuser_id . v ) ;
if ( user ) {
switch ( d . vstatus . type ( ) ) {
case mtpc_userStatusEmpty : user - > onlineTill = 0 ; break ;
case mtpc_userStatusRecently :
if ( user - > onlineTill > - 10 ) { // don't modify pseudo-online
user - > onlineTill = - 2 ;
}
break ;
case mtpc_userStatusLastWeek : user - > onlineTill = - 3 ; break ;
case mtpc_userStatusLastMonth : user - > onlineTill = - 4 ; break ;
case mtpc_userStatusOffline : user - > onlineTill = d . vstatus . c_userStatusOffline ( ) . vwas_online . v ; break ;
case mtpc_userStatusOnline : user - > onlineTill = d . vstatus . c_userStatusOnline ( ) . vexpires . v ; break ;
}
2015-06-30 01:09:23 +03:00
App : : markPeerUpdated ( user ) ;
2015-01-26 16:04:41 +03:00
}
if ( d . vuser_id . v = = MTP : : authedId ( ) ) {
if ( d . vstatus . type ( ) = = mtpc_userStatusOffline | | d . vstatus . type ( ) = = mtpc_userStatusEmpty ) {
updateOnline ( true ) ;
if ( d . vstatus . type ( ) = = mtpc_userStatusOffline ) {
cSetOtherOnline ( d . vstatus . c_userStatusOffline ( ) . vwas_online . v ) ;
2014-05-30 12:53:19 +04:00
}
2015-01-26 16:04:41 +03:00
} else if ( d . vstatus . type ( ) = = mtpc_userStatusOnline ) {
cSetOtherOnline ( d . vstatus . c_userStatusOnline ( ) . vexpires . v ) ;
2014-05-30 12:53:19 +04:00
}
}
} break ;
case mtpc_updateUserName : {
2016-05-25 15:09:05 +03:00
auto & d ( update . c_updateUserName ( ) ) ;
if ( auto user = App : : userLoaded ( d . vuser_id . v ) ) {
2014-11-15 02:23:35 +03:00
if ( user - > contact < = 0 ) {
2016-05-25 15:09:05 +03:00
user - > setNameDelayed ( textOneLine ( qs ( d . vfirst_name ) ) , textOneLine ( qs ( d . vlast_name ) ) , user - > nameOrPhone , textOneLine ( qs ( d . vusername ) ) ) ;
2014-11-15 02:23:35 +03:00
} else {
2016-05-25 15:09:05 +03:00
user - > setNameDelayed ( textOneLine ( user - > firstName ) , textOneLine ( user - > lastName ) , user - > nameOrPhone , textOneLine ( qs ( d . vusername ) ) ) ;
2014-11-15 02:23:35 +03:00
}
2015-06-30 01:09:23 +03:00
App : : markPeerUpdated ( user ) ;
2014-05-30 12:53:19 +04:00
}
} break ;
case mtpc_updateUserPhoto : {
2016-04-08 14:44:35 +04:00
const auto & d ( update . c_updateUserPhoto ( ) ) ;
2014-05-30 12:53:19 +04:00
UserData * user = App : : userLoaded ( d . vuser_id . v ) ;
if ( user ) {
user - > setPhoto ( d . vphoto ) ;
2016-03-18 13:18:30 +03:00
user - > loadUserpic ( ) ;
2015-10-28 20:16:52 -04:00
if ( mtpIsTrue ( d . vprevious ) ) {
2014-08-11 13:03:45 +04:00
user - > photosCount = - 1 ;
user - > photos . clear ( ) ;
} else {
2015-06-30 01:09:23 +03:00
if ( user - > photoId & & user - > photoId ! = UnknownPeerPhotoId ) {
2014-08-11 13:03:45 +04:00
if ( user - > photosCount > 0 ) + + user - > photosCount ;
user - > photos . push_front ( App : : photo ( user - > photoId ) ) ;
} else {
user - > photosCount = - 1 ;
user - > photos . clear ( ) ;
}
2014-05-30 12:53:19 +04:00
}
2015-06-30 01:09:23 +03:00
App : : markPeerUpdated ( user ) ;
2015-07-03 11:47:16 +03:00
if ( App : : wnd ( ) ) App : : wnd ( ) - > mediaOverviewUpdated ( user , OverviewCount ) ;
2014-05-30 12:53:19 +04:00
}
} break ;
case mtpc_updateContactRegistered : {
2016-04-08 14:44:35 +04:00
const auto & d ( update . c_updateContactRegistered ( ) ) ;
2014-05-30 12:53:19 +04:00
UserData * user = App : : userLoaded ( d . vuser_id . v ) ;
if ( user ) {
2014-07-04 15:12:54 +04:00
if ( App : : history ( user - > id ) - > loadedAtBottom ( ) ) {
2016-03-19 19:55:15 +03:00
App : : history ( user - > id ) - > addNewService ( clientMsgId ( ) , date ( d . vdate ) , lng_action_user_registered ( lt_from , user - > name ) , MTPDmessage : : Flag : : f_unread ) ;
2014-07-04 15:12:54 +04:00
}
2014-05-30 12:53:19 +04:00
}
} break ;
case mtpc_updateContactLink : {
2016-04-08 14:44:35 +04:00
const auto & d ( update . c_updateContactLink ( ) ) ;
2016-05-25 15:09:05 +03:00
App : : feedUserLinkDelayed ( d . vuser_id , d . vmy_link , d . vforeign_link ) ;
2014-05-30 12:53:19 +04:00
} break ;
2014-12-03 16:10:32 +03:00
case mtpc_updateNotifySettings : {
2016-04-08 14:44:35 +04:00
const auto & d ( update . c_updateNotifySettings ( ) ) ;
2014-12-03 16:10:32 +03:00
applyNotifySetting ( d . vpeer , d . vnotify_settings ) ;
} break ;
case mtpc_updateDcOptions : {
2016-04-08 14:44:35 +04:00
const auto & d ( update . c_updateDcOptions ( ) ) ;
2014-12-03 16:10:32 +03:00
MTP : : updateDcOptions ( d . vdc_options . c_vector ( ) . v ) ;
} break ;
case mtpc_updateUserPhone : {
2016-05-25 15:09:05 +03:00
auto & d ( update . c_updateUserPhone ( ) ) ;
if ( auto user = App : : userLoaded ( d . vuser_id . v ) ) {
2014-12-03 16:10:32 +03:00
user - > setPhone ( qs ( d . vphone ) ) ;
2016-05-25 15:09:05 +03:00
user - > setNameDelayed ( user - > firstName , user - > lastName , ( user - > contact | | isServiceUser ( user - > id ) | | user - > isSelf ( ) | | user - > phone . isEmpty ( ) ) ? QString ( ) : App : : formatPhone ( user - > phone ) , user - > username ) ;
2015-06-30 01:09:23 +03:00
App : : markPeerUpdated ( user ) ;
2014-12-03 16:10:32 +03:00
}
} break ;
2014-05-30 12:53:19 +04:00
case mtpc_updateNewEncryptedMessage : {
2016-04-08 14:44:35 +04:00
const auto & d ( update . c_updateNewEncryptedMessage ( ) ) ;
2014-05-30 12:53:19 +04:00
} break ;
case mtpc_updateEncryptedChatTyping : {
2016-04-08 14:44:35 +04:00
const auto & d ( update . c_updateEncryptedChatTyping ( ) ) ;
2014-05-30 12:53:19 +04:00
} break ;
case mtpc_updateEncryption : {
2016-04-08 14:44:35 +04:00
const auto & d ( update . c_updateEncryption ( ) ) ;
2014-05-30 12:53:19 +04:00
} break ;
case mtpc_updateEncryptedMessagesRead : {
2016-04-08 14:44:35 +04:00
const auto & d ( update . c_updateEncryptedMessagesRead ( ) ) ;
2014-05-30 12:53:19 +04:00
} break ;
case mtpc_updateUserBlocked : {
2016-04-08 14:44:35 +04:00
const auto & d ( update . c_updateUserBlocked ( ) ) ;
2015-08-12 21:01:32 +03:00
if ( UserData * user = App : : userLoaded ( d . vuser_id . v ) ) {
2015-10-28 20:16:52 -04:00
user - > blocked = mtpIsTrue ( d . vblocked ) ? UserIsBlocked : UserIsNotBlocked ;
2015-08-12 21:01:32 +03:00
App : : markPeerUpdated ( user ) ;
}
2014-05-30 12:53:19 +04:00
} break ;
2014-12-03 16:10:32 +03:00
case mtpc_updateNewAuthorization : {
2016-04-08 14:44:35 +04:00
const auto & d ( update . c_updateNewAuthorization ( ) ) ;
2014-12-12 19:27:03 +03:00
QDateTime datetime = date ( d . vdate ) ;
2015-04-02 13:33:19 +03:00
2014-12-18 21:40:49 +03:00
QString name = App : : self ( ) - > firstName ;
2015-12-21 16:14:29 +03:00
QString day = langDayOfWeekFull ( datetime . date ( ) ) , date = langDayOfMonthFull ( datetime . date ( ) ) , time = datetime . time ( ) . toString ( cTimeFormat ( ) ) ;
2014-12-18 21:40:49 +03:00
QString device = qs ( d . vdevice ) , location = qs ( d . vlocation ) ;
LangString text = lng_new_authorization ( lt_name , App : : self ( ) - > firstName , lt_day , day , lt_date , date , lt_time , time , lt_device , device , lt_location , location ) ;
2014-12-12 19:27:03 +03:00
App : : wnd ( ) - > serviceNotification ( text ) ;
2015-04-02 13:33:19 +03:00
emit App : : wnd ( ) - > newAuthorization ( ) ;
2014-08-01 22:49:43 +04:00
} break ;
2014-10-22 22:39:03 +04:00
case mtpc_updateServiceNotification : {
2016-04-08 14:44:35 +04:00
const auto & d ( update . c_updateServiceNotification ( ) ) ;
2015-10-28 20:16:52 -04:00
if ( mtpIsTrue ( d . vpopup ) ) {
2015-12-07 21:09:05 +03:00
Ui : : showLayer ( new InformBox ( qs ( d . vmessage ) ) ) ;
2014-12-12 19:27:03 +03:00
} else {
2015-09-20 11:55:41 +03:00
App : : wnd ( ) - > serviceNotification ( qs ( d . vmessage ) , d . vmedia ) ;
2014-12-05 16:44:27 +03:00
}
2014-12-03 16:10:32 +03:00
} break ;
case mtpc_updatePrivacy : {
2016-04-08 14:44:35 +04:00
const auto & d ( update . c_updatePrivacy ( ) ) ;
2014-10-22 22:39:03 +04:00
} break ;
2015-09-06 13:17:09 +03:00
2016-02-18 19:36:33 +03:00
/////// Channel updates
2015-09-20 11:55:41 +03:00
case mtpc_updateChannel : {
2016-04-08 14:44:35 +04:00
const auto & d ( update . c_updateChannel ( ) ) ;
2015-09-21 23:57:42 +03:00
if ( ChannelData * channel = App : : channelLoaded ( d . vchannel_id . v ) ) {
App : : markPeerUpdated ( channel ) ;
2015-09-22 12:58:40 +03:00
channel - > inviter = 0 ;
2015-09-23 20:43:08 +03:00
if ( ! channel - > amIn ( ) ) {
2015-09-24 11:58:10 +03:00
deleteConversation ( channel , false ) ;
2015-09-21 23:57:42 +03:00
} else if ( ! channel - > amCreator ( ) & & App : : history ( channel - > id ) ) { // create history
_updatedChannels . insert ( channel , true ) ;
2015-10-03 14:33:51 +03:00
if ( App : : api ( ) ) App : : api ( ) - > requestSelfParticipant ( channel ) ;
2015-09-21 23:57:42 +03:00
}
}
2015-09-20 11:55:41 +03:00
} break ;
2015-09-06 13:17:09 +03:00
case mtpc_updateNewChannelMessage : {
2016-04-08 14:44:35 +04:00
const auto & d ( update . c_updateNewChannelMessage ( ) ) ;
2015-09-20 12:54:22 +03:00
ChannelData * channel = App : : channelLoaded ( peerToChannel ( peerFromMessage ( d . vmessage ) ) ) ;
2016-04-06 15:07:05 +04:00
DataIsLoadedResult isDataLoaded = allDataLoadedForMessage ( d . vmessage ) ;
if ( ! _ptsWaiter . requesting ( ) & & ( ! channel | | isDataLoaded ! = DataIsLoadedResult : : Ok ) ) {
MTP_LOG ( 0 , ( " getDifference { good - after not all data loaded in updateNewChannelMessage }%1 " ) . arg ( cTestMode ( ) ? " TESTMODE " : " " ) ) ;
// Request last active supergroup participants if the 'from' user was not loaded yet.
// This will optimize similar getDifference() calls for almost all next messages.
if ( isDataLoaded = = DataIsLoadedResult : : FromNotLoaded & & channel & & channel - > isMegagroup ( ) & & App : : api ( ) ) {
if ( channel - > mgInfo - > lastParticipants . size ( ) < Global : : ChatSizeMax ( ) & & ( channel - > mgInfo - > lastParticipants . isEmpty ( ) | | channel - > mgInfo - > lastParticipants . size ( ) < channel - > count ) ) {
App : : api ( ) - > requestLastParticipants ( channel ) ;
}
}
2016-03-11 18:01:32 +03:00
if ( ! _byMinChannelTimer . isActive ( ) ) { // getDifference after timeout
_byMinChannelTimer . start ( WaitForSkippedTimeout ) ;
}
return ;
}
2015-09-21 23:57:42 +03:00
if ( channel & & ! _handlingChannelDifference ) {
if ( channel - > ptsRequesting ( ) ) { // skip global updates while getting channel difference
return ;
} else if ( ! channel - > ptsUpdated ( d . vpts . v , d . vpts_count . v , update ) ) {
return ;
}
2015-09-13 11:41:27 +03:00
}
2015-09-20 12:54:22 +03:00
// update before applying skipped
2015-10-15 02:15:28 +02:00
bool needToAdd = true ;
2016-04-13 00:31:28 +03:00
if ( d . vmessage . type ( ) = = mtpc_message ) { // index forwarded messages to links _overview
2015-10-15 02:15:28 +02:00
if ( App : : checkEntitiesAndViewsUpdate ( d . vmessage . c_message ( ) ) ) { // already in blocks
LOG ( ( " Skipping message, because it is already in blocks! " ) ) ;
needToAdd = false ;
}
2015-09-06 13:17:09 +03:00
}
2015-10-15 02:15:28 +02:00
if ( needToAdd ) {
HistoryItem * item = App : : histories ( ) . addNewMessage ( d . vmessage , NewMessageUnread ) ;
if ( item ) {
2016-04-13 00:31:28 +03:00
_history - > peerMessagesUpdated ( item - > history ( ) - > peer - > id ) ;
2015-10-15 02:15:28 +02:00
}
2015-09-06 13:17:09 +03:00
}
2015-09-21 23:57:42 +03:00
if ( channel & & ! _handlingChannelDifference ) {
2015-09-20 12:54:22 +03:00
channel - > ptsApplySkippedUpdates ( ) ;
}
2015-09-06 13:17:09 +03:00
} break ;
2016-02-18 19:36:33 +03:00
case mtpc_updateEditChannelMessage : {
2016-04-08 14:44:35 +04:00
const auto & d ( update . c_updateEditChannelMessage ( ) ) ;
2016-02-18 19:36:33 +03:00
ChannelData * channel = App : : channelLoaded ( peerToChannel ( peerFromMessage ( d . vmessage ) ) ) ;
if ( channel & & ! _handlingChannelDifference ) {
if ( channel - > ptsRequesting ( ) ) { // skip global updates while getting channel difference
return ;
} else if ( ! channel - > ptsUpdated ( d . vpts . v , d . vpts_count . v , update ) ) {
return ;
}
}
// update before applying skipped
if ( d . vmessage . type ( ) = = mtpc_message ) { // apply message edit
App : : updateEditedMessage ( d . vmessage . c_message ( ) ) ;
}
if ( channel & & ! _handlingChannelDifference ) {
channel - > ptsApplySkippedUpdates ( ) ;
}
} break ;
2016-03-30 21:13:07 +04:00
case mtpc_updateEditMessage : {
2016-04-08 14:44:35 +04:00
const auto & d ( update . c_updateEditMessage ( ) ) ;
2016-03-30 21:13:07 +04:00
if ( ! ptsUpdated ( d . vpts . v , d . vpts_count . v , update ) ) {
return ;
}
// update before applying skipped
if ( d . vmessage . type ( ) = = mtpc_message ) { // apply message edit
App : : updateEditedMessage ( d . vmessage . c_message ( ) ) ;
}
ptsApplySkippedUpdates ( ) ;
} break ;
2016-03-04 17:34:46 +02:00
case mtpc_updateChannelPinnedMessage : {
2016-04-08 14:44:35 +04:00
const auto & d ( update . c_updateChannelPinnedMessage ( ) ) ;
2016-03-04 17:34:46 +02:00
if ( ChannelData * channel = App : : channelLoaded ( d . vchannel_id . v ) ) {
if ( channel - > isMegagroup ( ) ) {
channel - > mgInfo - > pinnedMsgId = d . vid . v ;
if ( App : : api ( ) ) {
emit App : : api ( ) - > fullPeerUpdated ( channel ) ;
}
}
}
} break ;
2015-09-06 13:17:09 +03:00
case mtpc_updateReadChannelInbox : {
2016-04-08 14:44:35 +04:00
const auto & d ( update . c_updateReadChannelInbox ( ) ) ;
2015-09-21 23:57:42 +03:00
ChannelData * channel = App : : channelLoaded ( d . vchannel_id . v ) ;
2015-09-17 00:15:13 +03:00
App : : feedInboxRead ( peerFromChannel ( d . vchannel_id . v ) , d . vmax_id . v ) ;
2015-09-06 13:17:09 +03:00
} break ;
case mtpc_updateDeleteChannelMessages : {
2016-04-08 14:44:35 +04:00
const auto & d ( update . c_updateDeleteChannelMessages ( ) ) ;
2015-09-20 12:54:22 +03:00
ChannelData * channel = App : : channelLoaded ( d . vchannel_id . v ) ;
2015-09-21 23:57:42 +03:00
if ( channel & & ! _handlingChannelDifference ) {
if ( channel - > ptsRequesting ( ) ) { // skip global updates while getting channel difference
return ;
} else if ( ! channel - > ptsUpdated ( d . vpts . v , d . vpts_count . v , update ) ) {
return ;
}
2015-09-13 11:41:27 +03:00
}
2015-09-20 12:54:22 +03:00
// update before applying skipped
2015-09-17 00:15:13 +03:00
App : : feedWereDeleted ( d . vchannel_id . v , d . vmessages . c_vector ( ) . v ) ;
2016-04-13 00:31:28 +03:00
_history - > peerMessagesUpdated ( ) ;
2015-09-20 12:54:22 +03:00
2015-09-21 23:57:42 +03:00
if ( channel & & ! _handlingChannelDifference ) {
2015-09-20 12:54:22 +03:00
channel - > ptsApplySkippedUpdates ( ) ;
}
2015-09-06 13:17:09 +03:00
} break ;
case mtpc_updateChannelGroup : {
2015-09-21 23:57:42 +03:00
if ( ! _handlingChannelDifference ) {
LOG ( ( " API Error: got updateChannelGroup not in channelDifference! " ) ) ;
2015-09-13 11:41:27 +03:00
}
2015-09-06 13:17:09 +03:00
} break ;
case mtpc_updateChannelTooLong : {
2016-04-08 14:44:35 +04:00
const auto & d ( update . c_updateChannelTooLong ( ) ) ;
2015-09-13 11:41:27 +03:00
if ( ChannelData * channel = App : : channelLoaded ( d . vchannel_id . v ) ) {
2016-03-11 18:01:32 +03:00
if ( ! d . has_pts ( ) | | channel - > pts ( ) < d . vpts . v ) {
getChannelDifference ( channel ) ;
}
2015-09-13 11:41:27 +03:00
}
} break ;
case mtpc_updateChannelMessageViews : {
2016-04-08 14:44:35 +04:00
const auto & d ( update . c_updateChannelMessageViews ( ) ) ;
2015-09-17 00:15:13 +03:00
if ( HistoryItem * item = App : : histItemById ( d . vchannel_id . v , d . vid . v ) ) {
item - > setViewsCount ( d . vviews . v ) ;
2015-09-13 11:41:27 +03:00
}
2015-09-06 13:17:09 +03:00
} break ;
2016-02-18 19:36:33 +03:00
////// Cloud sticker sets
2015-12-02 20:17:53 +03:00
case mtpc_updateNewStickerSet : {
2016-04-08 14:44:35 +04:00
const auto & d ( update . c_updateNewStickerSet ( ) ) ;
2015-12-02 20:17:53 +03:00
if ( d . vstickerset . type ( ) = = mtpc_messages_stickerSet ) {
2016-04-08 14:44:35 +04:00
const auto & set ( d . vstickerset . c_messages_stickerSet ( ) ) ;
2015-12-02 20:17:53 +03:00
if ( set . vset . type ( ) = = mtpc_stickerSet ) {
2016-04-08 14:44:35 +04:00
const auto & s ( set . vset . c_stickerSet ( ) ) ;
2016-01-09 20:51:42 +08:00
2016-03-19 19:55:15 +03:00
Stickers : : Sets & sets ( Global : : RefStickerSets ( ) ) ;
auto it = sets . find ( s . vid . v ) ;
2016-01-09 20:51:42 +08:00
if ( it = = sets . cend ( ) ) {
2016-03-19 19:55:15 +03:00
it = sets . insert ( s . vid . v , Stickers : : Set ( s . vid . v , s . vaccess_hash . v , stickerSetTitle ( s ) , qs ( s . vshort_name ) , s . vcount . v , s . vhash . v , s . vflags . v ) ) ;
2016-01-09 20:51:42 +08:00
}
2016-04-08 14:44:35 +04:00
const auto & v ( set . vdocuments . c_vector ( ) . v ) ;
2016-01-09 20:51:42 +08:00
it - > stickers . clear ( ) ;
it - > stickers . reserve ( v . size ( ) ) ;
2015-12-02 20:17:53 +03:00
for ( int32 i = 0 , l = v . size ( ) ; i < l ; + + i ) {
DocumentData * doc = App : : feedDocument ( v . at ( i ) ) ;
if ( ! doc | | ! doc - > sticker ( ) ) continue ;
2016-01-09 20:51:42 +08:00
it - > stickers . push_back ( doc ) ;
2015-12-02 20:17:53 +03:00
}
2016-01-09 20:51:42 +08:00
it - > emoji . clear ( ) ;
2016-04-08 14:44:35 +04:00
const auto & packs ( set . vpacks . c_vector ( ) . v ) ;
2016-01-09 20:51:42 +08:00
for ( int32 i = 0 , l = packs . size ( ) ; i < l ; + + i ) {
if ( packs . at ( i ) . type ( ) ! = mtpc_stickerPack ) continue ;
2016-04-08 14:44:35 +04:00
const auto & pack ( packs . at ( i ) . c_stickerPack ( ) ) ;
2016-01-09 20:51:42 +08:00
if ( EmojiPtr e = emojiGetNoColor ( emojiFromText ( qs ( pack . vemoticon ) ) ) ) {
2016-04-08 14:44:35 +04:00
const auto & stickers ( pack . vdocuments . c_vector ( ) . v ) ;
2016-01-09 20:51:42 +08:00
StickerPack p ;
p . reserve ( stickers . size ( ) ) ;
for ( int32 j = 0 , c = stickers . size ( ) ; j < c ; + + j ) {
DocumentData * doc = App : : document ( stickers . at ( j ) . v ) ;
if ( ! doc | | ! doc - > sticker ( ) ) continue ;
p . push_back ( doc ) ;
}
it - > emoji . insert ( e , p ) ;
}
2016-01-09 19:24:16 +08:00
}
2015-12-02 20:17:53 +03:00
2016-03-19 19:55:15 +03:00
auto & order ( Global : : RefStickerSetsOrder ( ) ) ;
2015-12-02 20:17:53 +03:00
int32 insertAtIndex = 0 , currentIndex = order . indexOf ( s . vid . v ) ;
if ( currentIndex ! = insertAtIndex ) {
if ( currentIndex > 0 ) {
order . removeAt ( currentIndex ) ;
}
order . insert ( insertAtIndex , s . vid . v ) ;
}
2016-03-19 19:55:15 +03:00
auto custom = sets . find ( Stickers : : CustomSetId ) ;
2015-12-02 20:17:53 +03:00
if ( custom ! = sets . cend ( ) ) {
2016-01-09 20:51:42 +08:00
for ( int32 i = 0 , l = it - > stickers . size ( ) ; i < l ; + + i ) {
int32 removeIndex = custom - > stickers . indexOf ( it - > stickers . at ( i ) ) ;
2015-12-03 22:55:44 +03:00
if ( removeIndex > = 0 ) custom - > stickers . removeAt ( removeIndex ) ;
2015-12-02 20:17:53 +03:00
}
if ( custom - > stickers . isEmpty ( ) ) {
sets . erase ( custom ) ;
}
}
Local : : writeStickers ( ) ;
emit stickersUpdated ( ) ;
}
}
} break ;
case mtpc_updateStickerSetsOrder : {
2016-04-08 14:44:35 +04:00
const auto & d ( update . c_updateStickerSetsOrder ( ) ) ;
const auto & order ( d . vorder . c_vector ( ) . v ) ;
const auto & sets ( Global : : StickerSets ( ) ) ;
2016-03-19 19:55:15 +03:00
Stickers : : Order result ;
2015-12-02 20:17:53 +03:00
for ( int32 i = 0 , l = order . size ( ) ; i < l ; + + i ) {
if ( sets . constFind ( order . at ( i ) . v ) = = sets . cend ( ) ) {
break ;
}
result . push_back ( order . at ( i ) . v ) ;
}
2016-03-19 19:55:15 +03:00
if ( result . size ( ) ! = Global : : StickerSetsOrder ( ) . size ( ) | | result . size ( ) ! = order . size ( ) ) {
Global : : SetLastStickersUpdate ( 0 ) ;
2015-12-02 20:17:53 +03:00
App : : main ( ) - > updateStickers ( ) ;
} else {
2016-03-19 19:55:15 +03:00
Global : : SetStickerSetsOrder ( result ) ;
2015-12-02 20:17:53 +03:00
Local : : writeStickers ( ) ;
emit stickersUpdated ( ) ;
}
} break ;
case mtpc_updateStickerSets : {
2016-03-19 19:55:15 +03:00
Global : : SetLastStickersUpdate ( 0 ) ;
2015-12-28 00:37:48 +03:00
App : : main ( ) - > updateStickers ( ) ;
} break ;
case mtpc_updateSavedGifs : {
cSetLastSavedGifsUpdate ( 0 ) ;
2015-12-02 20:17:53 +03:00
App : : main ( ) - > updateStickers ( ) ;
} break ;
2014-05-30 12:53:19 +04:00
}
}