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"
# include "style.h"
# 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"
# include "window.h"
# include "settingswidget.h"
# include "mainwidget.h"
# 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"
2014-05-30 12:53:19 +04:00
2015-01-02 17:55:24 +03:00
# include "localstorage.h"
2014-09-04 11:33:44 +04:00
# include "audio.h"
2015-10-17 10:31:48 +02:00
TopBarWidget : : TopBarWidget ( MainWidget * w ) : TWidget ( w )
, a_over ( 0 )
2015-12-08 15:33:37 +03:00
, _a_appearance ( animation ( this , & TopBarWidget : : step_appearance ) )
2015-10-17 10:31:48 +02:00
, _selPeer ( 0 )
, _selCount ( 0 )
, _canDelete ( false )
, _selStrLeft ( - st : : topBarButton . width / 2 )
, _selStrWidth ( 0 )
, _animating ( false )
, _clearSelection ( this , lang ( lng_selected_clear ) , st : : topBarButton )
, _forward ( this , lang ( lng_selected_forward ) , st : : topBarActionButton )
, _delete ( this , lang ( lng_selected_delete ) , st : : topBarActionButton )
, _selectionButtonsWidth ( _clearSelection . width ( ) + _forward . width ( ) + _delete . width ( ) ) , _forwardDeleteWidth ( qMax ( _forward . textWidth ( ) , _delete . textWidth ( ) ) )
, _info ( this , lang ( lng_topbar_info ) , st : : topBarButton )
, _edit ( this , lang ( lng_profile_edit_contact ) , st : : topBarButton )
, _leaveGroup ( this , lang ( lng_profile_delete_and_exit ) , st : : topBarButton )
, _addContact ( this , lang ( lng_profile_add_contact ) , st : : topBarButton )
, _deleteContact ( this , lang ( lng_profile_delete_contact ) , st : : topBarButton )
, _mediaType ( this , lang ( lng_media_type ) , st : : topBarButton )
, _sideShadow ( this , st : : shadowColor ) {
2014-05-30 12:53:19 +04:00
connect ( & _forward , SIGNAL ( clicked ( ) ) , this , SLOT ( onForwardSelection ( ) ) ) ;
connect ( & _delete , SIGNAL ( clicked ( ) ) , this , SLOT ( onDeleteSelection ( ) ) ) ;
connect ( & _clearSelection , SIGNAL ( clicked ( ) ) , this , SLOT ( onClearSelection ( ) ) ) ;
2014-12-15 18:55:45 +03:00
connect ( & _info , SIGNAL ( clicked ( ) ) , this , SLOT ( onInfoClicked ( ) ) ) ;
2014-05-30 12:53:19 +04:00
connect ( & _addContact , SIGNAL ( clicked ( ) ) , this , SLOT ( onAddContact ( ) ) ) ;
connect ( & _deleteContact , SIGNAL ( clicked ( ) ) , this , SLOT ( onDeleteContact ( ) ) ) ;
connect ( & _edit , SIGNAL ( clicked ( ) ) , this , SLOT ( onEdit ( ) ) ) ;
connect ( & _leaveGroup , SIGNAL ( clicked ( ) ) , this , SLOT ( onDeleteAndExit ( ) ) ) ;
setCursor ( style : : cur_pointer ) ;
showAll ( ) ;
}
void TopBarWidget : : onForwardSelection ( ) {
if ( App : : main ( ) ) App : : main ( ) - > forwardSelectedItems ( ) ;
}
void TopBarWidget : : onDeleteSelection ( ) {
if ( App : : main ( ) ) App : : main ( ) - > deleteSelectedItems ( ) ;
}
void TopBarWidget : : onClearSelection ( ) {
if ( App : : main ( ) ) App : : main ( ) - > clearSelectedItems ( ) ;
}
2014-12-15 18:55:45 +03:00
void TopBarWidget : : onInfoClicked ( ) {
PeerData * p = App : : main ( ) ? App : : main ( ) - > historyPeer ( ) : 0 ;
if ( p ) App : : main ( ) - > showPeerProfile ( p ) ;
2014-05-30 12:53:19 +04:00
}
void TopBarWidget : : onAddContact ( ) {
PeerData * p = App : : main ( ) ? App : : main ( ) - > profilePeer ( ) : 0 ;
2015-09-03 13:48:40 +03:00
UserData * u = p ? p - > asUser ( ) : 0 ;
2015-12-07 21:09:05 +03:00
if ( u ) Ui : : showLayer ( new AddContactBox ( u - > firstName , u - > lastName , u - > phone . isEmpty ( ) ? App : : phoneFromSharedContact ( peerToUser ( u - > id ) ) : u - > phone ) ) ;
2014-05-30 12:53:19 +04:00
}
2014-12-15 18:55:45 +03:00
void TopBarWidget : : onEdit ( ) {
PeerData * p = App : : main ( ) ? App : : main ( ) - > profilePeer ( ) : 0 ;
2015-09-21 23:57:42 +03:00
if ( p ) {
if ( p - > isChannel ( ) ) {
2015-12-07 21:09:05 +03:00
Ui : : showLayer ( new EditChannelBox ( p - > asChannel ( ) ) ) ;
2015-10-06 22:49:23 +03:00
} else if ( p - > isChat ( ) ) {
2015-12-07 21:09:05 +03:00
Ui : : showLayer ( new EditNameTitleBox ( p ) ) ;
2015-10-11 10:37:24 +02:00
} else if ( p - > isUser ( ) ) {
2015-12-07 21:09:05 +03:00
Ui : : showLayer ( new AddContactBox ( p - > asUser ( ) ) ) ;
2015-09-21 23:57:42 +03:00
}
}
2014-12-15 18:55:45 +03:00
}
2014-05-30 12:53:19 +04:00
void TopBarWidget : : onDeleteContact ( ) {
PeerData * p = App : : main ( ) ? App : : main ( ) - > profilePeer ( ) : 0 ;
2015-09-03 13:48:40 +03:00
UserData * u = p ? p - > asUser ( ) : 0 ;
2014-05-30 12:53:19 +04:00
if ( u ) {
2015-10-03 13:09:09 +03:00
ConfirmBox * box = new ConfirmBox ( lng_sure_delete_contact ( lt_contact , p - > name ) , lang ( lng_box_delete ) ) ;
2014-05-30 12:53:19 +04:00
connect ( box , SIGNAL ( confirmed ( ) ) , this , SLOT ( onDeleteContactSure ( ) ) ) ;
2015-12-07 21:09:05 +03:00
Ui : : showLayer ( box ) ;
2014-05-30 12:53:19 +04:00
}
}
void TopBarWidget : : onDeleteContactSure ( ) {
PeerData * p = App : : main ( ) ? App : : main ( ) - > profilePeer ( ) : 0 ;
2015-09-03 13:48:40 +03:00
UserData * u = p ? p - > asUser ( ) : 0 ;
2014-05-30 12:53:19 +04:00
if ( u ) {
2015-12-13 14:36:08 +03:00
Ui : : showChatsList ( ) ;
2015-12-07 21:09:05 +03:00
Ui : : hideLayer ( ) ;
2014-05-30 12:53:19 +04:00
MTP : : send ( MTPcontacts_DeleteContact ( u - > inputUser ) , App : : main ( ) - > rpcDone ( & MainWidget : : deletedContact , u ) ) ;
}
}
void TopBarWidget : : onDeleteAndExit ( ) {
PeerData * p = App : : main ( ) ? App : : main ( ) - > profilePeer ( ) : 0 ;
2015-09-03 13:48:40 +03:00
ChatData * c = p ? p - > asChat ( ) : 0 ;
2014-05-30 12:53:19 +04:00
if ( c ) {
2015-10-03 13:09:09 +03:00
ConfirmBox * box = new ConfirmBox ( lng_sure_delete_and_exit ( lt_group , p - > name ) , lang ( lng_box_leave ) , st : : attentionBoxButton ) ;
2014-05-30 12:53:19 +04:00
connect ( box , SIGNAL ( confirmed ( ) ) , this , SLOT ( onDeleteAndExitSure ( ) ) ) ;
2015-12-07 21:09:05 +03:00
Ui : : showLayer ( box ) ;
2014-05-30 12:53:19 +04:00
}
}
void TopBarWidget : : onDeleteAndExitSure ( ) {
PeerData * p = App : : main ( ) ? App : : main ( ) - > profilePeer ( ) : 0 ;
2015-09-03 13:48:40 +03:00
ChatData * c = p ? p - > asChat ( ) : 0 ;
2014-05-30 12:53:19 +04:00
if ( c ) {
2015-12-13 14:36:08 +03:00
Ui : : showChatsList ( ) ;
2015-12-07 21:09:05 +03:00
Ui : : hideLayer ( ) ;
2015-09-03 13:48:40 +03:00
MTP : : send ( MTPmessages_DeleteChatUser ( c - > inputChat , App : : self ( ) - > inputUser ) , App : : main ( ) - > rpcDone ( & MainWidget : : deleteHistoryAfterLeave , p ) , App : : main ( ) - > rpcFail ( & MainWidget : : leaveChatFailed , p ) ) ;
2014-05-30 12:53:19 +04:00
}
}
void TopBarWidget : : enterEvent ( QEvent * e ) {
a_over . start ( 1 ) ;
2015-12-08 15:33:37 +03:00
_a_appearance . start ( ) ;
2014-05-30 12:53:19 +04:00
}
2014-12-15 18:55:45 +03:00
void TopBarWidget : : enterFromChildEvent ( QEvent * e ) {
a_over . start ( 1 ) ;
2015-12-08 15:33:37 +03:00
_a_appearance . start ( ) ;
2014-12-15 18:55:45 +03:00
}
2014-05-30 12:53:19 +04:00
void TopBarWidget : : leaveEvent ( QEvent * e ) {
a_over . start ( 0 ) ;
2015-12-08 15:33:37 +03:00
_a_appearance . start ( ) ;
2014-05-30 12:53:19 +04:00
}
2014-12-15 18:55:45 +03:00
void TopBarWidget : : leaveToChildEvent ( QEvent * e ) {
a_over . start ( 0 ) ;
2015-12-08 15:33:37 +03:00
_a_appearance . start ( ) ;
2014-12-15 18:55:45 +03:00
}
2015-12-08 15:33:37 +03:00
void TopBarWidget : : step_appearance ( float64 ms , bool timer ) {
2014-05-30 12:53:19 +04:00
float64 dt = ms / st : : topBarDuration ;
if ( dt > = 1 ) {
2015-12-08 15:33:37 +03:00
_a_appearance . stop ( ) ;
2014-05-30 12:53:19 +04:00
a_over . finish ( ) ;
} else {
a_over . update ( dt , anim : : linear ) ;
}
2015-12-08 15:33:37 +03:00
if ( timer ) update ( ) ;
2014-05-30 12:53:19 +04:00
}
void TopBarWidget : : paintEvent ( QPaintEvent * e ) {
QPainter p ( this ) ;
2014-12-12 19:27:03 +03:00
2014-11-22 12:45:04 +03:00
if ( e - > rect ( ) . top ( ) < st : : topBarHeight ) { // optimize shadow-only drawing
2014-05-30 12:53:19 +04:00
p . fillRect ( QRect ( 0 , 0 , width ( ) , st : : topBarHeight ) , st : : topBarBG - > b ) ;
if ( _clearSelection . isHidden ( ) ) {
p . save ( ) ;
2014-12-15 18:55:45 +03:00
main ( ) - > paintTopBar ( p , a_over . current ( ) , _info . isHidden ( ) ? 0 : _info . width ( ) ) ;
2014-05-30 12:53:19 +04:00
p . restore ( ) ;
} else {
p . setFont ( st : : linkFont - > f ) ;
p . setPen ( st : : btnDefLink . color - > p ) ;
2014-12-23 02:11:37 +03:00
p . drawText ( _selStrLeft , st : : topBarButton . textTop + st : : linkFont - > ascent , _selStr ) ;
2014-05-30 12:53:19 +04:00
}
}
}
void TopBarWidget : : mousePressEvent ( QMouseEvent * e ) {
PeerData * p = App : : main ( ) ? App : : main ( ) - > profilePeer ( ) : 0 ;
if ( e - > button ( ) = = Qt : : LeftButton & & e - > pos ( ) . y ( ) < st : : topBarHeight & & ( p | | ! _selCount ) ) {
emit clicked ( ) ;
}
}
void TopBarWidget : : resizeEvent ( QResizeEvent * e ) {
int32 r = width ( ) ;
2015-09-06 13:17:09 +03:00
if ( ! _forward . isHidden ( ) | | ! _delete . isHidden ( ) ) {
2014-12-23 02:11:37 +03:00
int32 fullW = r - ( _selectionButtonsWidth + ( _selStrWidth - st : : topBarButton . width ) + st : : topBarActionSkip ) ;
int32 selectedClearWidth = st : : topBarButton . width , forwardDeleteWidth = st : : topBarActionButton . width - _forwardDeleteWidth , skip = st : : topBarActionSkip ;
while ( fullW < 0 ) {
int fit = 0 ;
if ( selectedClearWidth < - 2 * ( st : : topBarMinPadding + 1 ) ) {
fullW + = 4 ;
selectedClearWidth + = 2 ;
} else if ( selectedClearWidth < - 2 * st : : topBarMinPadding ) {
fullW + = ( - 2 * st : : topBarMinPadding - selectedClearWidth ) * 2 ;
selectedClearWidth = - 2 * st : : topBarMinPadding ;
} else {
+ + fit ;
}
if ( fullW > = 0 ) break ;
if ( forwardDeleteWidth > 2 * ( st : : topBarMinPadding + 1 ) ) {
fullW + = 4 ;
forwardDeleteWidth - = 2 ;
} else if ( forwardDeleteWidth > 2 * st : : topBarMinPadding ) {
fullW + = ( forwardDeleteWidth - 2 * st : : topBarMinPadding ) * 2 ;
forwardDeleteWidth = 2 * st : : topBarMinPadding ;
} else {
+ + fit ;
}
if ( fullW > = 0 ) break ;
if ( skip > st : : topBarMinPadding ) {
- - skip ;
+ + fullW ;
} else {
+ + fit ;
}
if ( fullW > = 0 | | fit > = 3 ) break ;
}
_clearSelection . setWidth ( selectedClearWidth ) ;
_forward . setWidth ( _forwardDeleteWidth + forwardDeleteWidth ) ;
_delete . setWidth ( _forwardDeleteWidth + forwardDeleteWidth ) ;
_selStrLeft = - selectedClearWidth / 2 ;
int32 availX = _selStrLeft + _selStrWidth , availW = r - ( _clearSelection . width ( ) + selectedClearWidth / 2 ) - availX ;
2015-09-06 13:17:09 +03:00
if ( _forward . isHidden ( ) ) {
_delete . move ( availX + ( availW - _delete . width ( ) ) / 2 , ( st : : topBarHeight - _forward . height ( ) ) / 2 ) ;
} else if ( _delete . isHidden ( ) ) {
_forward . move ( availX + ( availW - _forward . width ( ) ) / 2 , ( st : : topBarHeight - _forward . height ( ) ) / 2 ) ;
} else {
_forward . move ( availX + ( availW - _forward . width ( ) - _delete . width ( ) - skip ) / 2 , ( st : : topBarHeight - _forward . height ( ) ) / 2 ) ;
_delete . move ( availX + ( availW + _forward . width ( ) - _delete . width ( ) + skip ) / 2 , ( st : : topBarHeight - _forward . height ( ) ) / 2 ) ;
}
2014-12-23 02:11:37 +03:00
_clearSelection . move ( r - = _clearSelection . width ( ) , 0 ) ;
2014-05-30 12:53:19 +04:00
}
2014-12-15 18:55:45 +03:00
if ( ! _info . isHidden ( ) ) _info . move ( r - = _info . width ( ) , 0 ) ;
2014-05-30 12:53:19 +04:00
if ( ! _deleteContact . isHidden ( ) ) _deleteContact . move ( r - = _deleteContact . width ( ) , 0 ) ;
if ( ! _leaveGroup . isHidden ( ) ) _leaveGroup . move ( r - = _leaveGroup . width ( ) , 0 ) ;
if ( ! _edit . isHidden ( ) ) _edit . move ( r - = _edit . width ( ) , 0 ) ;
if ( ! _addContact . isHidden ( ) ) _addContact . move ( r - = _addContact . width ( ) , 0 ) ;
2014-08-21 16:18:56 +04:00
if ( ! _mediaType . isHidden ( ) ) _mediaType . move ( r - = _mediaType . width ( ) , 0 ) ;
2015-10-17 10:31:48 +02:00
_sideShadow . resize ( st : : lineWidth , height ( ) ) ;
_sideShadow . moveToLeft ( 0 , 0 ) ;
2014-05-30 12:53:19 +04:00
}
2014-06-14 23:32:11 +04:00
void TopBarWidget : : startAnim ( ) {
2014-12-15 18:55:45 +03:00
_info . hide ( ) ;
2014-05-30 12:53:19 +04:00
_edit . hide ( ) ;
_leaveGroup . hide ( ) ;
_addContact . hide ( ) ;
_deleteContact . hide ( ) ;
2014-06-14 23:32:11 +04:00
_clearSelection . hide ( ) ;
_delete . hide ( ) ;
_forward . hide ( ) ;
2014-08-21 16:18:56 +04:00
_mediaType . hide ( ) ;
2015-10-17 10:31:48 +02:00
_animating = true ;
2014-06-14 23:32:11 +04:00
}
void TopBarWidget : : stopAnim ( ) {
_animating = false ;
2016-02-08 17:54:55 +03:00
_sideShadow . setVisible ( ! Adaptive : : OneColumn ( ) ) ;
2015-10-17 10:31:48 +02:00
showAll ( ) ;
2014-05-30 12:53:19 +04:00
}
void TopBarWidget : : showAll ( ) {
2014-06-14 23:32:11 +04:00
if ( _animating ) {
resizeEvent ( 0 ) ;
return ;
}
2015-09-13 20:27:29 +03:00
PeerData * p = App : : main ( ) ? App : : main ( ) - > profilePeer ( ) : 0 , * h = App : : main ( ) ? App : : main ( ) - > historyPeer ( ) : 0 , * o = App : : main ( ) ? App : : main ( ) - > overviewPeer ( ) : 0 ;
2015-09-03 13:48:40 +03:00
if ( p & & ( p - > isChat ( ) | | ( p - > isUser ( ) & & ( p - > asUser ( ) - > contact > = 0 | | ! App : : phoneFromSharedContact ( peerToUser ( p - > id ) ) . isEmpty ( ) ) ) ) ) {
if ( p - > isChat ( ) ) {
2015-11-02 00:49:25 -05:00
if ( p - > asChat ( ) - > canEdit ( ) ) {
2014-05-30 12:53:19 +04:00
_edit . show ( ) ;
2015-10-29 15:10:49 -04:00
} else {
_edit . hide ( ) ;
2014-05-30 12:53:19 +04:00
}
_leaveGroup . show ( ) ;
_addContact . hide ( ) ;
_deleteContact . hide ( ) ;
} else if ( p - > asUser ( ) - > contact > 0 ) {
_edit . show ( ) ;
_leaveGroup . hide ( ) ;
_addContact . hide ( ) ;
_deleteContact . show ( ) ;
} else {
_edit . hide ( ) ;
_leaveGroup . hide ( ) ;
_addContact . show ( ) ;
_deleteContact . hide ( ) ;
}
_clearSelection . hide ( ) ;
2014-12-15 18:55:45 +03:00
_info . hide ( ) ;
2014-05-30 12:53:19 +04:00
_delete . hide ( ) ;
_forward . hide ( ) ;
2014-08-21 16:18:56 +04:00
_mediaType . hide ( ) ;
2014-05-30 12:53:19 +04:00
} else {
2015-11-23 19:05:30 +03:00
if ( p & & p - > isChannel ( ) & & ( p - > asChannel ( ) - > amCreator ( ) | | ( p - > isMegagroup ( ) & & p - > asChannel ( ) - > amEditor ( ) ) ) ) {
2015-09-04 16:01:31 +03:00
_edit . show ( ) ;
} else {
_edit . hide ( ) ;
}
2014-05-30 12:53:19 +04:00
_leaveGroup . hide ( ) ;
_addContact . hide ( ) ;
_deleteContact . hide ( ) ;
if ( ! p & & _selCount ) {
_clearSelection . show ( ) ;
2015-09-20 11:55:41 +03:00
if ( _canDelete ) {
2015-09-13 20:27:29 +03:00
_delete . show ( ) ;
2015-09-20 11:55:41 +03:00
} else {
_delete . hide ( ) ;
2015-09-13 20:27:29 +03:00
}
2015-09-12 14:59:50 +03:00
_forward . show ( ) ;
2014-08-21 16:18:56 +04:00
_mediaType . hide ( ) ;
2014-05-30 12:53:19 +04:00
} else {
_clearSelection . hide ( ) ;
_delete . hide ( ) ;
_forward . hide ( ) ;
2014-08-21 16:18:56 +04:00
if ( App : : main ( ) & & App : : main ( ) - > mediaTypeSwitch ( ) ) {
_mediaType . show ( ) ;
} else {
_mediaType . hide ( ) ;
}
2014-05-30 12:53:19 +04:00
}
2016-02-08 17:54:55 +03:00
if ( App : : main ( ) & & App : : main ( ) - > historyPeer ( ) & & ! o & & ! p & & _clearSelection . isHidden ( ) & & Adaptive : : OneColumn ( ) ) {
2014-12-15 18:55:45 +03:00
_info . show ( ) ;
} else {
_info . hide ( ) ;
}
2014-05-30 12:53:19 +04:00
}
2016-02-08 17:54:55 +03:00
_sideShadow . setVisible ( ! Adaptive : : OneColumn ( ) ) ;
2014-05-30 12:53:19 +04:00
resizeEvent ( 0 ) ;
}
2015-09-20 11:55:41 +03:00
void TopBarWidget : : showSelected ( uint32 selCount , bool canDelete ) {
2014-05-30 12:53:19 +04:00
PeerData * p = App : : main ( ) ? App : : main ( ) - > profilePeer ( ) : 0 ;
2015-09-06 13:17:09 +03:00
_selPeer = App : : main ( ) - > overviewPeer ( ) ? App : : main ( ) - > overviewPeer ( ) : App : : main ( ) - > peer ( ) ;
2014-05-30 12:53:19 +04:00
_selCount = selCount ;
2015-09-20 11:55:41 +03:00
_canDelete = canDelete ;
2014-12-18 21:40:49 +03:00
_selStr = ( _selCount > 0 ) ? lng_selected_count ( lt_count , _selCount ) : QString ( ) ;
2015-10-03 13:09:09 +03:00
_selStrWidth = st : : btnDefLink . font - > width ( _selStr ) ;
2014-05-30 12:53:19 +04:00
setCursor ( ( ! p & & _selCount ) ? style : : cur_default : style : : cur_pointer ) ;
showAll ( ) ;
}
2016-02-08 17:54:55 +03:00
void TopBarWidget : : updateAdaptiveLayout ( ) {
2015-10-17 16:52:26 +02:00
showAll ( ) ;
}
2014-08-21 16:18:56 +04:00
FlatButton * TopBarWidget : : mediaTypeButton ( ) {
return & _mediaType ;
}
2014-05-30 12:53:19 +04:00
MainWidget * TopBarWidget : : main ( ) {
return static_cast < MainWidget * > ( parentWidget ( ) ) ;
}
2015-10-17 16:52:26 +02:00
MainWidget : : MainWidget ( Window * window ) : TWidget ( window )
, _started ( 0 )
, failedObjId ( 0 )
, _toForwardNameVersion ( 0 )
2015-12-08 15:33:37 +03:00
, _a_show ( animation ( this , & MainWidget : : step_show ) )
2015-10-19 01:01:18 +02:00
, _dialogsWidth ( st : : dlgMinWidth )
2015-10-17 16:52:26 +02:00
, dialogs ( this )
, history ( this )
, profile ( 0 )
, overview ( 0 )
, _player ( this )
, _topBar ( this )
, _forwardConfirm ( 0 )
, _hider ( 0 )
, _peerInStack ( 0 )
, _msgIdInStack ( 0 )
, _playerHeight ( 0 )
, _contentScrollAddToY ( 0 )
, _mediaType ( this )
, _mediaTypeMask ( 0 )
, updDate ( 0 )
, updQts ( - 1 )
, updSeq ( 0 )
, _getDifferenceTimeByPts ( 0 )
, _getDifferenceTimeAfterFail ( 0 )
, _onlineRequest ( 0 )
, _lastWasOnline ( false )
, _lastSetOnline ( 0 )
, _isIdle ( false )
, _failDifferenceTimeout ( 1 )
, _lastUpdateTime ( 0 )
, _handlingChannelDifference ( false )
, _cachedX ( 0 )
, _cachedY ( 0 )
, _background ( 0 )
, _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 & ) ) ) ;
2014-05-30 12:53:19 +04: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 ( ) ) ) ;
connect ( & _failDifferenceTimer , SIGNAL ( timeout ( ) ) , this , SLOT ( onGetDifferenceTimeAfterFail ( ) ) ) ;
2015-09-21 23:57:42 +03:00
connect ( _api , SIGNAL ( fullPeerUpdated ( PeerData * ) ) , this , SLOT ( onFullPeerUpdated ( PeerData * ) ) ) ;
2014-05-30 12:53:19 +04:00
connect ( this , SIGNAL ( peerUpdated ( PeerData * ) ) , & history , SLOT ( peerUpdated ( PeerData * ) ) ) ;
connect ( & _topBar , SIGNAL ( clicked ( ) ) , this , SLOT ( onTopBarClick ( ) ) ) ;
2015-10-03 13:09:09 +03:00
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 ( ) ) ) ;
2014-05-30 12:53:19 +04:00
dialogs . show ( ) ;
2016-02-08 17:54:55 +03:00
if ( Adaptive : : OneColumn ( ) ) {
2014-12-12 19:27:03 +03:00
history . hide ( ) ;
2016-02-08 17:54:55 +03:00
} else {
history . show ( ) ;
2014-12-12 19:27:03 +03:00
}
App : : wnd ( ) - > getTitle ( ) - > updateBackButton ( ) ;
2014-05-30 12:53:19 +04:00
_topBar . hide ( ) ;
2015-07-03 11:47:16 +03:00
_player . hide ( ) ;
2015-07-17 22:17:37 +03:00
orderWidgets ( ) ;
2014-05-30 12:53:19 +04:00
MTP : : setGlobalFailHandler ( rpcFail ( & MainWidget : : updateFail ) ) ;
2014-08-21 16:18:56 +04:00
_mediaType . hide ( ) ;
_topBar . mediaTypeButton ( ) - > installEventFilter ( & _mediaType ) ;
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 ( ) ;
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 ;
}
2015-03-24 13:00:27 +03:00
history . cancelReply ( ) ;
_toForward . clear ( ) ;
2015-06-27 16:02:00 +03:00
if ( what = = ForwardSelectedMessages ) {
2014-08-20 09:32:50 +04:00
if ( overview ) {
2015-03-24 13:00:27 +03:00
overview - > fillSelectedItems ( _toForward , false ) ;
2014-08-20 09:32:50 +04:00
} else {
2015-03-24 13:00:27 +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 ) ;
2015-03-24 13:00:27 +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-02-25 13:32:31 +03:00
h - > setMsgDraft ( new HistoryDraft ( url + ' \n ' + text , 0 , MessageCursor ( url . size ( ) + 1 , url . size ( ) + 1 + text . size ( ) , QFIXED_MAX ) , false ) ) ;
2016-02-27 22:39:51 +03:00
h - > setEditDraft ( nullptr ) ;
2015-10-18 14:49:34 +02:00
bool opened = history . peer ( ) & & ( history . peer ( ) - > id = = peer ) ;
if ( opened ) {
history . applyDraft ( ) ;
} 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 ( ) ;
history . cancelForwarding ( ) ;
}
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-02-17 19:37:21 +03:00
int32 sendFlags = 0 , flags = 0 ;
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 ) {
sendFlags | = MTPmessages_ForwardMessages : : flag_broadcast ;
flags | = MTPDmessage : : flag_views ;
flags | = MTPDmessage : : flag_post ;
}
if ( showFromName ) {
flags | = MTPDmessage : : flag_from_id ;
}
2016-02-25 19:19:54 +03:00
if ( silentPost ) {
sendFlags | = MTPmessages_ForwardMessages : : flag_silent ;
}
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 ) {
2015-03-24 13:00:27 +03:00
uint64 randomId = MTP : : nonce < 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-02-17 19:37:21 +03:00
hist - > sendRequestId = MTP : : send ( MTPmessages_ForwardMessages ( MTP_int ( 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-02-17 19:37:21 +03:00
hist - > sendRequestId = MTP : : send ( MTPmessages_ForwardMessages ( MTP_int ( 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
2015-11-13 18:14:33 +03:00
if ( history . peer ( ) = = hist - > peer ) {
history . peerMessagesUpdated ( ) ;
}
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 ( ) ;
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 ) {
k . key ( ) - > initDimensions ( ) ;
2015-12-22 11:01:02 +03:00
Notify : : historyItemResized ( k . key ( ) ) ;
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 ( ) {
history . updateStickers ( ) ;
}
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 ) {
history . onShareContact ( peer , contact ) ;
}
2014-07-18 14:37:34 +04:00
void MainWidget : : onSendPaths ( const PeerId & peer ) {
history . onSendPaths ( peer ) ;
}
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 ) ;
2015-06-27 16:02:00 +03:00
history . onFilesDrop ( data ) ;
}
2015-06-26 12:07:59 +03:00
}
2015-10-17 16:52:26 +02:00
QPixmap MainWidget : : grabInner ( ) {
if ( overview & & ! overview - > isHidden ( ) ) {
return myGrab ( overview ) ;
} else if ( profile & & ! profile - > isHidden ( ) ) {
return myGrab ( profile ) ;
2016-02-08 17:54:55 +03:00
} else if ( Adaptive : : OneColumn ( ) & & history . isHidden ( ) ) {
2015-10-17 16:52:26 +02:00
return myGrab ( & dialogs , QRect ( 0 , st : : topBarHeight , dialogs . width ( ) , dialogs . height ( ) - st : : topBarHeight ) ) ;
} else if ( history . peer ( ) ) {
return myGrab ( & history ) ;
} else {
return myGrab ( & history , QRect ( 0 , st : : topBarHeight , history . width ( ) , history . height ( ) - st : : topBarHeight ) ) ;
}
}
2015-12-23 19:48:44 +03:00
bool MainWidget : : isItemVisible ( HistoryItem * item ) {
if ( isHidden ( ) | | _a_show . animating ( ) ) {
return false ;
}
return history . isItemVisible ( item ) ;
}
2015-10-17 16:52:26 +02:00
QPixmap MainWidget : : grabTopBar ( ) {
if ( ! _topBar . isHidden ( ) ) {
return myGrab ( & _topBar ) ;
2016-02-08 17:54:55 +03:00
} else if ( Adaptive : : OneColumn ( ) & & history . isHidden ( ) ) {
2015-10-17 16:52:26 +02:00
return myGrab ( & dialogs , QRect ( 0 , 0 , dialogs . width ( ) , st : : topBarHeight ) ) ;
} else {
return myGrab ( & history , QRect ( 0 , 0 , history . width ( ) , st : : topBarHeight ) ) ;
}
}
2015-12-11 21:11:38 +03:00
void MainWidget : : notify_botCommandsChanged ( UserData * bot ) {
history . notify_botCommandsChanged ( bot ) ;
}
2016-01-01 17:58:05 +08:00
void MainWidget : : notify_inlineBotRequesting ( bool requesting ) {
history . notify_inlineBotRequesting ( requesting ) ;
}
2015-12-11 21:11:38 +03:00
void MainWidget : : notify_userIsBotChanged ( UserData * bot ) {
history . notify_userIsBotChanged ( bot ) ;
}
2015-12-13 14:17:15 +03:00
void MainWidget : : notify_userIsContactChanged ( UserData * user , bool fromThisApp ) {
if ( ! user ) return ;
dialogs . notify_userIsContactChanged ( user , fromThisApp ) ;
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 ) {
j . key ( ) - > initDimensions ( ) ;
2015-12-28 00:37:48 +03:00
Ui : : repaintHistoryItem ( j . key ( ) ) ;
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 ) {
history . notify_migrateUpdated ( peer ) ;
}
2015-12-28 00:37:48 +03:00
void MainWidget : : notify_clipStopperHidden ( ClipStopperType type ) {
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 ) {
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
}
2015-12-28 00:37:48 +03:00
if ( overview ) overview - > ui_repaintHistoryItem ( item ) ;
}
2015-12-31 03:09:20 +08:00
void MainWidget : : ui_repaintInlineItem ( const LayoutInlineItem * layout ) {
history . ui_repaintInlineItem ( layout ) ;
2015-12-28 00:37:48 +03:00
}
2015-12-31 03:09:20 +08:00
bool MainWidget : : ui_isInlineItemVisible ( const LayoutInlineItem * layout ) {
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 ( ) {
return history . ui_isInlineItemBeingChosen ( ) ;
2015-12-13 01:29:33 +03:00
}
void MainWidget : : notify_historyItemLayoutChanged ( const HistoryItem * item ) {
history . notify_historyItemLayoutChanged ( item ) ;
2015-12-22 15:49:42 +03:00
if ( overview ) overview - > notify_historyItemLayoutChanged ( item ) ;
2015-12-11 21:11:38 +03:00
}
2015-12-31 23:27:21 +08:00
void MainWidget : : notify_automaticLoadSettingsChangedGif ( ) {
history . notify_automaticLoadSettingsChangedGif ( ) ;
}
2016-02-27 22:39:51 +03:00
void MainWidget : : cmd_search ( ) {
history . cmd_search ( ) ;
}
void MainWidget : : cmd_next_chat ( ) {
history . cmd_next_chat ( ) ;
}
void MainWidget : : cmd_previous_chat ( ) {
history . cmd_previous_chat ( ) ;
}
2015-12-22 11:01:02 +03:00
void MainWidget : : notify_historyItemResized ( const HistoryItem * item , bool scrollToIt ) {
if ( ! item | | ( ( history . peer ( ) = = item - > history ( ) - > peer | | ( history . peer ( ) & & history . peer ( ) = = item - > history ( ) - > peer - > migrateTo ( ) ) ) & & ! item - > detached ( ) ) ) {
history . notify_historyItemResized ( item , scrollToIt ) ;
} else if ( item ) {
item - > history ( ) - > width = 0 ;
if ( history . peer ( ) = = item - > history ( ) - > peer | | ( history . peer ( ) & & history . peer ( ) = = item - > history ( ) - > peer - > migrateTo ( ) ) ) {
history . resizeEvent ( 0 ) ;
}
}
2015-12-28 00:37:48 +03:00
if ( item ) Ui : : repaintHistoryItem ( item ) ;
2015-12-22 11:01:02 +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 ) {
_hider = 0 ;
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 ;
}
2015-10-03 13:09:09 +03:00
onHistoryShown ( history . history ( ) , history . msgId ( ) ) ;
2014-12-12 19:27:03 +03:00
if ( profile | | overview | | ( history . peer ( ) & & history . peer ( ) - > id ) ) {
2015-10-17 16:52:26 +02:00
QPixmap animCache = grabInner ( ) , animTopBarCache = grabTopBar ( ) ;
2014-12-12 19:27:03 +03:00
dialogs . hide ( ) ;
if ( overview ) {
overview - > show ( ) ;
overview - > animShow ( animCache , animTopBarCache ) ;
} else if ( profile ) {
profile - > show ( ) ;
profile - > animShow ( animCache , animTopBarCache ) ;
} else {
history . show ( ) ;
history . animShow ( animCache , animTopBarCache ) ;
}
}
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 ;
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 ( ) ;
2015-07-03 11:47:16 +03:00
QPixmap animCache = myGrab ( this , QRect ( 0 , _playerHeight , _dialogsWidth , height ( ) - _playerHeight ) ) ;
2014-12-12 19:27:03 +03:00
2015-10-03 13:09:09 +03:00
onHistoryShown ( 0 , 0 ) ;
2014-12-12 19:27:03 +03:00
if ( overview ) {
overview - > hide ( ) ;
} else if ( profile ) {
profile - > hide ( ) ;
} else {
history . hide ( ) ;
}
dialogs . show ( ) ;
resizeEvent ( 0 ) ;
dialogs . animShow ( animCache ) ;
App : : wnd ( ) - > getTitle ( ) - > updateBackButton ( ) ;
2016-02-08 17:54:55 +03:00
} else {
_hider - > show ( ) ;
resizeEvent ( 0 ) ;
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 ) {
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 ( ) ) ) ;
}
}
2014-08-20 09:32:50 +04:00
connect ( box , SIGNAL ( confirmed ( ) ) , overview ? overview : static_cast < QWidget * > ( & history ) , SLOT ( onDeleteContextSure ( ) ) ) ;
2014-05-30 12:53:19 +04:00
} else {
2014-08-20 09:32:50 +04:00
connect ( box , SIGNAL ( confirmed ( ) ) , overview ? 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 ) ) ;
}
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
}
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 ( ) {
dialogs . activate ( ) ;
}
2015-06-24 20:24:48 +03:00
DragState MainWidget : : getDragState ( const QMimeData * mime ) {
return history . getDragState ( mime ) ;
}
2015-04-04 23:01:34 +03:00
bool MainWidget : : leaveChatFailed ( PeerData * peer , const RPCError & error ) {
2015-10-06 22:49:23 +03:00
if ( mtpIsFlood ( 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 ) {
const MTPDmessages_affectedHistory & d ( result . c_messages_affectedHistory ( ) ) ;
2015-09-20 12:54:22 +03:00
if ( ptsUpdated ( d . vpts . v , d . vpts_count . v ) ) {
ptsApplySkippedUpdates ( ) ;
App : : emitPeerUpdated ( ) ;
}
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 ) {
const MTPDcontacts_link & d ( result . c_contacts_link ( ) ) ;
2015-06-30 01:09:23 +03:00
App : : feedUsers ( MTP_vector < MTPUser > ( 1 , d . vuser ) , false ) ;
2015-09-03 13:48:40 +03:00
App : : feedUserLink ( MTP_int ( peerToUser ( user - > id ) ) , d . vmy_link , d . vforeign_link , false ) ;
2015-06-30 01:09:23 +03:00
App : : emitPeerUpdated ( ) ;
2014-05-30 12:53:19 +04:00
}
2015-11-13 18:14:33 +03:00
void MainWidget : : removeDialog ( History * history ) {
dialogs . removeDialog ( history ) ;
}
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
}
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 ) {
2015-09-17 00:15:13 +03:00
if ( mtpIsFlood ( 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 ) ;
2015-04-04 23:01:34 +03:00
if ( error . type ( ) = = " USER_LEFT_CHAT " ) { // trying to return banned user to his group
2016-02-14 21:29:17 +03:00
} else if ( error . type ( ) = = " USER_PRIVACY_RESTRICTED " ) {
text = lang ( lng_cant_invite_privacy ) ;
2015-08-07 15:11:50 +03:00
} else if ( error . type ( ) = = " USER_NOT_MUTUAL_CONTACT " ) { // trying to return user who does not have me in contacts
text = lang ( lng_failed_add_not_mutual ) ;
2015-06-15 20:19:24 +03:00
} else if ( error . type ( ) = = " USER_ALREADY_PARTICIPANT " & & user - > botInfo ) {
text = lang ( lng_bot_already_in_group ) ;
2015-09-09 10:46:31 +03:00
} else if ( error . type ( ) = = " PEER_FLOOD " ) {
2015-09-10 16:20:22 +03:00
text = lng_cant_invite_not_contact ( lt_more_info , textcmdLink ( qsl ( " https://telegram.org/faq?_hash=can-39t-send-messages-to-non-contacts " ) , lang ( lng_cant_more_info ) ) ) ;
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 ) {
2015-09-17 00:15:13 +03:00
if ( mtpIsFlood ( error ) ) return false ;
QString text = lang ( lng_failed_add_participant ) ;
if ( error . type ( ) = = " USER_LEFT_CHAT " ) { // trying to return banned user to his group
2016-02-14 21:29:17 +03:00
} else if ( error . type ( ) = = " USER_PRIVACY_RESTRICTED " ) {
text = lang ( lng_cant_invite_privacy_channel ) ;
2015-09-17 00:15:13 +03:00
} else if ( error . type ( ) = = " 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 ) ;
2015-09-17 00:15:13 +03:00
} else if ( error . type ( ) = = " PEER_FLOOD " ) {
text = lng_cant_invite_not_contact ( lt_more_info , textcmdLink ( qsl ( " https://telegram.org/faq?_hash=can-39t-send-messages-to-non-contacts " ) , lang ( lng_cant_more_info ) ) ) ;
}
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 ) {
2015-10-06 22:49:23 +03:00
if ( mtpIsFlood ( 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 : {
2014-05-30 12:53:19 +04:00
const MTPDmessages_messages & d ( result . c_messages_messages ( ) ) ;
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 : {
2014-05-30 12:53:19 +04:00
const MTPDmessages_messagesSlice & d ( result . c_messages_messagesSlice ( ) ) ;
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 : {
2015-09-04 16:01:31 +03:00
const MTPDmessages_channelMessages & 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 ) ;
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 ) ;
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 ) {
if ( mtpIsFlood ( error ) ) return false ;
if ( error . type ( ) = = qsl ( " PEER_FLOOD " ) ) {
2015-12-07 21:09:05 +03:00
Ui : : showLayer ( new InformBox ( lng_cant_send_to_not_contact ( lt_more_info , textcmdLink ( qsl ( " https://telegram.org/faq?_hash=can-39t-send-messages-to-non-contacts " ) , lang ( lng_cant_more_info ) ) ) ) ) ;
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 ( ) {
2014-08-20 09:32:50 +04:00
if ( overview ) {
overview - > onForwardSelected ( ) ;
} else {
history . onForwardSelected ( ) ;
}
2014-05-30 12:53:19 +04:00
}
void MainWidget : : deleteSelectedItems ( ) {
2014-08-20 09:32:50 +04:00
if ( overview ) {
overview - > onDeleteSelected ( ) ;
} else {
history . onDeleteSelected ( ) ;
}
2014-05-30 12:53:19 +04:00
}
void MainWidget : : clearSelectedItems ( ) {
2014-08-20 09:32:50 +04:00
if ( overview ) {
overview - > onClearSelected ( ) ;
} else {
history . onClearSelected ( ) ;
}
2014-05-30 12:53:19 +04:00
}
DialogsIndexed & MainWidget : : contactsList ( ) {
return dialogs . contactsList ( ) ;
}
2015-06-15 20:19:24 +03:00
DialogsIndexed & MainWidget : : dialogsList ( ) {
return dialogs . dialogsList ( ) ;
}
2016-02-25 19:19:54 +03:00
void MainWidget : : sendMessage ( History * hist , const QString & text , MsgId replyTo , bool broadcast , bool silent , WebPageId webPageId ) {
2015-10-23 18:06:56 +02:00
readServerHistory ( hist , false ) ;
history . fastShowAtEnd ( hist ) ;
2015-08-30 17:57:21 +03:00
2015-10-23 18:06:56 +02:00
if ( ! hist | | ! history . canSendMessages ( hist - > peer ) ) {
return ;
2015-08-30 17:57:21 +03:00
}
2015-08-24 13:53:04 +03:00
2015-03-24 13:00:27 +03:00
saveRecentHashtags ( text ) ;
2015-10-23 18:06:56 +02:00
EntitiesInText sendingEntities , leftEntities ;
QString sendingText , leftText = prepareTextWithEntities ( text , leftEntities , itemTextOptions ( hist , App : : self ( ) ) . flags ) ;
2015-03-19 12:18:19 +03:00
if ( replyTo < 0 ) replyTo = history . replyToId ( ) ;
2015-10-23 18:06:56 +02:00
while ( textSplit ( sendingText , sendingEntities , leftText , leftEntities , MaxMessageSize ) ) {
2015-09-03 13:48:40 +03:00
FullMsgId newId ( peerToChannel ( hist - > peer - > id ) , clientMsgId ( ) ) ;
2014-06-15 16:31:03 +04:00
uint64 randomId = MTP : : nonce < uint64 > ( ) ;
2014-11-05 20:43:32 +03:00
2015-10-23 18:06:56 +02:00
trimTextWithEntities ( sendingText , sendingEntities ) ;
2015-08-24 13:53:04 +03:00
2014-06-15 16:31:03 +04:00
App : : historyRegRandom ( randomId , newId ) ;
2015-09-03 13:48:40 +03:00
App : : historyRegSentData ( randomId , hist - > peer - > id , sendingText ) ;
2014-07-04 15:12:54 +04:00
2014-11-05 20:43:32 +03:00
MTPstring msgText ( MTP_string ( sendingText ) ) ;
2015-08-28 19:30:32 +03:00
int32 flags = newMessageFlags ( hist - > peer ) | MTPDmessage : : flag_entities ; // unread, out
2015-04-07 01:15:29 +03:00
int32 sendFlags = 0 ;
if ( replyTo ) {
flags | = MTPDmessage : : flag_reply_to_msg_id ;
sendFlags | = MTPmessages_SendMessage : : flag_reply_to_msg_id ;
}
2015-04-08 02:03:32 +03:00
MTPMessageMedia media = MTP_messageMediaEmpty ( ) ;
2016-02-21 15:30:16 +03:00
if ( webPageId = = CancelledWebPageId ) {
2015-10-28 20:16:52 -04:00
sendFlags | = MTPmessages_SendMessage : : flag_no_webpage ;
2015-04-08 02:03:32 +03:00
} else if ( webPageId ) {
WebPageData * page = App : : webPage ( webPageId ) ;
media = MTP_messageMediaWebPage ( MTP_webPagePending ( MTP_long ( page - > id ) , MTP_int ( page - > pendingTill ) ) ) ;
2015-08-31 17:27:20 +03:00
flags | = MTPDmessage : : flag_media ;
2015-04-08 02:03:32 +03:00
}
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 ) {
2015-11-02 17:33:57 -05:00
sendFlags | = MTPmessages_SendMessage : : flag_broadcast ;
2015-09-15 11:50:54 +03:00
flags | = MTPDmessage : : flag_views ;
2016-02-17 19:37:21 +03:00
flags | = MTPDmessage : : flag_post ;
}
if ( showFromName ) {
2015-09-06 13:17:09 +03:00
flags | = MTPDmessage : : flag_from_id ;
}
2016-02-25 19:19:54 +03:00
if ( silentPost ) {
sendFlags | = MTPmessages_SendMessage : : flag_silent ;
}
2015-10-23 18:06:56 +02:00
MTPVector < MTPMessageEntity > localEntities = linksToMTP ( sendingEntities ) , sentEntities = linksToMTP ( sendingEntities , true ) ;
if ( ! sentEntities . c_vector ( ) . v . isEmpty ( ) ) {
sendFlags | = MTPmessages_SendMessage : : flag_entities ;
}
2016-02-18 19:36:33 +03:00
hist - > addNewMessage ( MTP_message ( MTP_int ( flags ) , MTP_int ( newId . msg ) , MTP_int ( showFromName ? MTP : : authedId ( ) : 0 ) , peerToMTP ( hist - > peer - > id ) , MTPnullFwdHeader , MTPint ( ) , MTP_int ( replyTo ) , MTP_int ( unixtime ( ) ) , msgText , media , MTPnullMarkup , localEntities , MTP_int ( 1 ) , MTPint ( ) ) , NewMessageUnread ) ;
2015-10-23 18:06:56 +02:00
hist - > sendRequestId = MTP : : send ( MTPmessages_SendMessage ( MTP_int ( sendFlags ) , hist - > peer - > input , MTP_int ( replyTo ) , msgText , MTP_long ( randomId ) , MTPnullMarkup , sentEntities ) , rpcDone ( & MainWidget : : sentUpdatesReceived , randomId ) , rpcFail ( & MainWidget : : sendMessageFail ) , 0 , 0 , hist - > sendRequestId ) ;
2014-11-05 20:43:32 +03:00
}
2016-02-25 19:19:54 +03:00
finishForwarding ( hist , broadcast , silent ) ;
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 ) {
2015-07-17 22:17:37 +03: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 ( ) ) {
return ; // no read request for channels that I didn't koin
}
ReadRequests : : const_iterator i = _readRequests . constFind ( hist - > peer ) ;
2014-06-15 16:31:03 +04: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 {
return history . animActiveTimeStart ( msg ) ;
2014-07-04 15:12:54 +04:00
}
void MainWidget : : stopAnimActive ( ) {
history . stopAnimActive ( ) ;
}
2015-06-15 20:19:24 +03:00
void MainWidget : : sendBotCommand ( const QString & cmd , MsgId replyTo ) {
history . sendBotCommand ( cmd , replyTo ) ;
2015-06-10 18:54:24 +03:00
}
2016-01-01 02:34:56 +08:00
bool MainWidget : : insertBotCommand ( const QString & cmd , bool specialGif ) {
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 ( ) ;
2015-09-21 23:57:42 +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 {
dialogs . activate ( ) ;
}
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 ;
}
int32 flags = ( peer - > isChannel ( ) & & ! peer - > isMegagroup ( ) ) ? MTPmessages_Search : : flag_important_only : 0 ;
_overviewPreload [ type ] . insert ( peer , MTP : : send ( MTPmessages_Search ( MTP_int ( 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 ) ) ;
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 ) {
if ( profile ) profile - > mediaOverviewUpdated ( peer , type ) ;
if ( ! _player . isHidden ( ) ) _player . mediaOverviewUpdated ( peer , type ) ;
2015-11-16 19:04:37 +03:00
if ( overview & & ( overview - > peer ( ) = = peer | | overview - > peer ( ) - > migrateFrom ( ) = = peer ) ) {
2015-07-03 11:47:16 +03:00
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 ) {
2015-11-18 16:11:56 +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 ) {
_mediaType . resetButtons ( ) ;
for ( int32 i = 0 ; i < OverviewCount ; + + i ) {
if ( mask & ( 1 < < i ) ) {
switch ( i ) {
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 ;
2016-02-12 19:35:06 +03:00
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 ;
2015-08-28 18:15:56 +03:00
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 ;
_mediaType . move ( width ( ) - _mediaType . width ( ) , st : : topBarHeight ) ;
overview - > updateTopBarSelection ( ) ;
}
}
2014-08-15 15:19:32 +04:00
}
2014-08-20 23:13:00 +04:00
void MainWidget : : changingMsgId ( HistoryItem * row , MsgId newId ) {
if ( overview ) overview - > changingMsgId ( row , newId ) ;
}
2014-10-10 16:46:20 +04:00
void MainWidget : : itemRemoved ( HistoryItem * item ) {
2015-03-19 12:18:19 +03:00
api ( ) - > itemRemoved ( item ) ;
2014-10-10 16:46:20 +04:00
dialogs . itemRemoved ( item ) ;
2015-11-13 18:14:33 +03:00
if ( history . peer ( ) = = item - > history ( ) - > peer | | ( history . peer ( ) & & history . peer ( ) = = item - > history ( ) - > peer - > migrateTo ( ) ) ) {
2014-10-10 16:46:20 +04:00
history . itemRemoved ( item ) ;
}
2015-11-13 18:14:33 +03:00
if ( overview & & ( overview - > peer ( ) = = item - > history ( ) - > peer | | ( overview - > peer ( ) & & overview - > peer ( ) = = item - > history ( ) - > peer - > migrateTo ( ) ) ) ) {
2015-08-28 18:15:56 +03:00
overview - > itemRemoved ( item ) ;
}
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
}
2014-08-15 15:19:32 +04:00
bool MainWidget : : overviewFailed ( PeerData * peer , const RPCError & error , mtpRequestId req ) {
2015-10-06 22:49:23 +03:00
if ( mtpIsFlood ( 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 ;
2015-11-02 17:33:57 -05:00
int32 flags = ( peer - > isChannel ( ) & & ! peer - > isMegagroup ( ) ) ? MTPmessages_Search : : flag_important_only : 0 ;
2015-11-18 16:11:56 +03:00
_overviewLoad [ type ] . insert ( peer , MTP : : send ( MTPmessages_Search ( MTP_int ( 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-10-22 22:39:03 +04:00
void MainWidget : : peerUsernameChanged ( PeerData * peer ) {
if ( profile & & profile - > peer ( ) = = peer ) {
2015-09-21 23:57:42 +03:00
profile - > peerUsernameChanged ( ) ;
2014-10-22 22:39:03 +04:00
}
if ( App : : settings ( ) & & peer = = App : : self ( ) ) {
App : : settings ( ) - > usernameChanged ( ) ;
}
}
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 ( ) {
dialogs . onAddContact ( ) ;
}
2014-11-18 15:40:43 +03:00
void MainWidget : : showNewGroup ( ) {
dialogs . onNewGroup ( ) ;
}
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 ( ) ) {
2015-09-17 00:15:13 +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 {
2015-10-29 15:10:49 -04: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 ) {
2015-10-06 22:49:23 +03:00
if ( mtpIsFlood ( 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 ) {
2015-03-19 12:18:19 +03:00
const MTPDmessages_affectedMessages & 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 ( ) ;
App : : emitPeerUpdated ( ) ;
}
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 ( ) ;
App : : emitPeerUpdated ( ) ;
}
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
}
2015-12-13 14:17:15 +03:00
void MainWidget : : ui_showPeerHistoryAsync ( quint64 peerId , qint32 showAtMsgId ) {
Ui : : showPeerHistory ( peerId , showAtMsgId ) ;
}
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 ;
2015-05-24 20:58:39 +03:00
QString already = audio - > already ( true ) ;
2015-12-24 22:26:28 +03:00
if ( already . isEmpty ( ) & & ! audio - > data ( ) . isEmpty ( ) ) {
2015-06-27 16:02:00 +03:00
bool mp3 = ( audio - > mime = = qstr ( " audio/mp3 " ) ) ;
2015-05-24 20:58:39 +03:00
QString filename = saveFileName ( lang ( lng_save_audio ) , mp3 ? qsl ( " MP3 Audio (*.mp3);;All files (*.*) " ) : qsl ( " OGG Opus Audio (*.ogg);;All files (*.*) " ) , qsl ( " audio " ) , mp3 ? qsl ( " .mp3 " ) : qsl ( " .ogg " ) , false ) ;
if ( ! filename . isEmpty ( ) ) {
QFile f ( filename ) ;
if ( f . open ( QIODevice : : WriteOnly ) ) {
2015-12-24 22:26:28 +03:00
if ( f . write ( audio - > data ( ) ) = = audio - > data ( ) . size ( ) ) {
2015-05-24 20:58:39 +03:00
f . close ( ) ;
already = filename ;
2015-11-26 20:34:52 +03:00
audio - > setLocation ( FileLocation ( StorageFilePartial , filename ) ) ;
2016-02-12 19:35:06 +03:00
Local : : writeFileLocation ( mediaKey ( AudioFileLocation , audio - > dc , audio - > id ) , FileLocation ( mtpToStorageType ( mtpc_storage_filePartial ) , filename ) ) ;
2015-05-24 20:58:39 +03:00
}
}
}
}
if ( ! already . isEmpty ( ) ) {
psOpenFile ( already ) ;
}
}
2015-07-01 00:07:05 +03:00
if ( HistoryItem * item = App : : histItemById ( audioId . msgId ) ) {
2015-12-28 00:37:48 +03:00
Ui : : repaintHistoryItem ( 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 ;
QString already = document - > already ( true ) ;
2015-12-24 22:26:28 +03:00
if ( already . isEmpty ( ) & & ! document - > data ( ) . isEmpty ( ) ) {
2015-07-01 00:07:05 +03:00
QString name = document - > name , filter ;
MimeType mimeType = mimeTypeForName ( document - > mime ) ;
QStringList p = mimeType . globPatterns ( ) ;
QString pattern = p . isEmpty ( ) ? QString ( ) : p . front ( ) ;
if ( name . isEmpty ( ) ) {
name = pattern . isEmpty ( ) ? qsl ( " .unknown " ) : pattern . replace ( ' * ' , QString ( ) ) ;
}
if ( pattern . isEmpty ( ) ) {
2015-10-18 13:38:00 +02:00
filter = QString ( ) ;
2015-07-01 00:07:05 +03:00
} else {
filter = mimeType . filterString ( ) + qsl ( " ;;All files (*.*) " ) ;
}
QString filename = saveFileName ( lang ( lng_save_file ) , filter , qsl ( " doc " ) , name , false ) ;
if ( ! filename . isEmpty ( ) ) {
QFile f ( filename ) ;
if ( f . open ( QIODevice : : WriteOnly ) ) {
2015-12-24 22:26:28 +03:00
if ( f . write ( document - > data ( ) ) = = document - > data ( ) . size ( ) ) {
2015-07-01 00:07:05 +03:00
f . close ( ) ;
already = filename ;
2015-11-26 20:34:52 +03:00
document - > setLocation ( FileLocation ( StorageFilePartial , filename ) ) ;
2016-02-12 19:35:06 +03:00
Local : : writeFileLocation ( mediaKey ( DocumentFileLocation , document - > dc , document - > id ) , FileLocation ( mtpToStorageType ( mtpc_storage_filePartial ) , filename ) ) ;
2015-07-01 00:07:05 +03:00
}
}
}
2014-09-04 11:33:44 +04:00
}
2015-07-01 00:07:05 +03:00
if ( ! already . isEmpty ( ) ) {
psOpenFile ( already ) ;
}
}
2015-07-03 11:47:16 +03:00
if ( playing = = songId ) {
_player . updateState ( playing , playingState , playingPosition , playingDuration , playingFrequency ) ;
2015-10-17 16:52:26 +02:00
if ( ! ( playingState & AudioPlayerStoppedMask ) & & playingState ! = AudioPlayerFinishing & & ! _a_show . animating ( ) ) {
2015-07-03 11:47:16 +03:00
if ( _player . isHidden ( ) ) {
_player . clearSelection ( ) ;
_player . show ( ) ;
_playerHeight = _contentScrollAddToY = _player . height ( ) ;
resizeEvent ( 0 ) ;
}
}
}
2015-07-01 00:07:05 +03:00
if ( HistoryItem * item = App : : histItemById ( songId . msgId ) ) {
2015-12-28 00:37:48 +03:00
Ui : : repaintHistoryItem ( item ) ;
2014-09-04 11:33:44 +04:00
}
}
2015-07-03 11:47:16 +03:00
void MainWidget : : hidePlayer ( ) {
if ( ! _player . isHidden ( ) ) {
_player . hide ( ) ;
_contentScrollAddToY = - _player . height ( ) ;
_playerHeight = 0 ;
resizeEvent ( 0 ) ;
}
}
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 ) ;
if ( playing . song = = document & & ! _player . isHidden ( ) ) {
2015-12-24 22:26:28 +03:00
_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 ) {
//InlineResult *result = App::inlineResultFromLoader(loader);
//if (!result) return;
//result->loaded();
//Ui::repaintInlineItem();
}
void MainWidget : : inlineResultLoadFailed ( FileLoader * loader , bool started ) {
//InlineResult *result = App::inlineResultFromLoader(loader);
//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 ;
2014-06-15 16:31:03 +04:00
history . updateOnlineDisplay ( history . x ( ) , width ( ) - history . x ( ) - st : : sysBtnDelta * 2 - st : : sysCls . img . pxWidth ( ) - st : : sysRes . img . pxWidth ( ) - st : : sysMin . img . pxWidth ( ) ) ;
2014-05-30 12:53:19 +04:00
if ( profile ) profile - > updateOnlineDisplay ( ) ;
if ( App : : wnd ( ) - > settingsWidget ( ) ) App : : wnd ( ) - > settingsWidget ( ) - > updateOnlineDisplay ( ) ;
}
2015-10-26 22:39:02 -04:00
void MainWidget : : onSendFileConfirm ( const FileLoadResultPtr & file , bool ctrlShiftEnter ) {
bool lastKeyboardUsed = history . lastForceReplyReplied ( FullMsgId ( peerToChannel ( file - > to . peer ) , file - > to . replyTo ) ) ;
history . confirmSendFile ( file , ctrlShiftEnter ) ;
history . cancelReply ( lastKeyboardUsed ) ;
}
void MainWidget : : onSendFileCancel ( const FileLoadResultPtr & file ) {
history . cancelSendFile ( file ) ;
}
2015-10-27 22:41:13 -04:00
void MainWidget : : onShareContactConfirm ( const QString & phone , const QString & fname , const QString & lname , MsgId replyTo , bool ctrlShiftEnter ) {
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 ( ) {
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
}
2015-07-17 22:17:37 +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 ) {
2015-10-28 20:16:52 -04:00
int32 flags = MTPDmessage : : flag_unread | MTPDmessage : : flag_entities | MTPDmessage : : flag_from_id ;
2015-02-20 18:41:54 +03:00
QString sendingText , leftText = msg ;
2015-10-23 18:06:56 +02:00
EntitiesInText sendingEntities , leftEntities = textParseEntities ( leftText , _historyTextNoMonoOptions . flags ) ;
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-02-18 19:36:33 +03:00
item = App : : histories ( ) . addNewMessage ( MTP_message ( MTP_int ( 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 ) {
history . peerMessagesUpdated ( item - > history ( ) - > peer - > id ) ;
}
}
void MainWidget : : serviceHistoryDone ( const MTPmessages_Messages & msgs ) {
switch ( msgs . type ( ) ) {
2015-09-04 16:01:31 +03:00
case mtpc_messages_messages : {
const MTPDmessages_messages & d ( msgs . c_messages_messages ( ) ) ;
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 : {
const MTPDmessages_messagesSlice & d ( msgs . c_messages_messagesSlice ( ) ) ;
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 : {
const MTPDmessages_channelMessages & 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 ) {
2015-10-06 22:49:23 +03:00
if ( mtpIsFlood ( 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 ( ) {
history . updateScrollColors ( ) ;
if ( overview ) overview - > updateScrollColors ( ) ;
}
void MainWidget : : setChatBackground ( const App : : WallPaper & wp ) {
_background = new 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
}
delete _background ;
_background = 0 ;
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 ( ) {
return _api ;
}
2016-03-05 23:12:55 +02:00
void MainWidget : : updateDependencyItem ( ) {
2016-02-25 13:32:31 +03:00
history . updateReplyEditTexts ( true ) ;
2015-03-19 12:18:19 +03:00
}
2015-11-24 19:19:18 +03:00
void MainWidget : : updateBotKeyboard ( History * h ) {
history . updateBotKeyboard ( h ) ;
2015-06-18 20:24:54 +03:00
}
2015-03-24 13:00:27 +03:00
void MainWidget : : pushReplyReturn ( HistoryItem * item ) {
history . pushReplyReturn ( item ) ;
}
2014-05-30 12:53:19 +04:00
void MainWidget : : setInnerFocus ( ) {
2015-07-17 22:17:37 +03:00
if ( _hider | | ! history . peer ( ) ) {
if ( _hider & & _hider - > wasOffered ( ) ) {
_hider - > setFocus ( ) ;
2014-09-21 20:52:37 -07:00
} else if ( overview ) {
overview - > activate ( ) ;
} else if ( profile ) {
profile - > activate ( ) ;
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
}
2015-10-12 23:02:10 +02:00
} else if ( overview ) {
overview - > activate ( ) ;
2014-09-21 20:52:37 -07:00
} else if ( profile ) {
2015-10-12 23:02:10 +02:00
profile - > activate ( ) ;
2014-05-30 12:53:19 +04:00
} else {
2015-09-16 16:04:08 +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 ( ) {
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 ) {
const QVector < MTPint > & v ( result . c_vector ( ) . v ) ;
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 ) {
if ( mtpIsFlood ( error ) ) return false ;
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 {
return history . atTopImportantMsg ( bottomUnderScrollTop ) ;
}
2015-09-21 23:57:42 +03:00
void MainWidget : : createDialog ( History * history ) {
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 ( ) {
history . contactsReceived ( ) ;
}
2015-09-12 22:00:56 +03:00
void MainWidget : : updateAfterDrag ( ) {
if ( overview ) {
overview - > updateAfterDrag ( ) ;
} else {
history . updateAfterDrag ( ) ;
}
}
2015-09-16 16:04:08 +03:00
void MainWidget : : ctrlEnterSubmitUpdated ( ) {
history . ctrlEnterSubmitUpdated ( ) ;
}
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 ( ) ) {
peerId = peer - > migrateTo ( ) - > id ;
if ( showAtMsgId > 0 ) showAtMsgId = - showAtMsgId ;
}
}
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 ( ) ;
_hider = 0 ;
}
2014-05-30 12:53:19 +04:00
QPixmap animCache , animTopBarCache ;
2016-02-08 17:54:55 +03:00
if ( ! _a_show . animating ( ) & & ( ( history . isHidden ( ) & & ( profile | | overview ) ) | | ( Adaptive : : OneColumn ( ) & & ( history . isHidden ( ) | | ! peerId ) ) ) ) {
2015-07-17 22:17:37 +03:00
if ( peerId ) {
2015-10-17 16:52:26 +02:00
animCache = grabInner ( ) ;
2016-02-08 17:54:55 +03:00
} else if ( Adaptive : : OneColumn ( ) ) {
2015-07-17 22:17:37 +03:00
animCache = myGrab ( this , QRect ( 0 , _playerHeight , _dialogsWidth , height ( ) - _playerHeight ) ) ;
2016-02-08 17:54:55 +03:00
} else {
animCache = myGrab ( this , QRect ( _dialogsWidth , _playerHeight , width ( ) - _dialogsWidth , height ( ) - _playerHeight ) ) ;
2014-05-30 12:53:19 +04:00
}
2016-02-08 17:54:55 +03:00
if ( peerId | | ! Adaptive : : OneColumn ( ) ) {
2015-10-17 16:52:26 +02:00
animTopBarCache = grabTopBar ( ) ;
2015-07-17 22:17:37 +03:00
}
history . show ( ) ;
2014-05-30 12:53:19 +04:00
}
2015-07-17 22:17:37 +03:00
if ( history . peer ( ) & & history . peer ( ) - > id ! = peerId ) clearBotStartToken ( history . peer ( ) ) ;
2015-11-09 12:51:22 +03:00
history . showHistory ( peerId , showAtMsgId ) ;
2015-07-17 22:17:37 +03:00
2016-02-08 17:54:55 +03:00
bool noPeer = ( ! history . peer ( ) | | ! history . peer ( ) - > id ) , onlyDialogs = noPeer & & Adaptive : : OneColumn ( ) ;
2015-07-17 22:17:37 +03:00
if ( profile | | overview ) {
if ( profile ) {
profile - > hide ( ) ;
profile - > clear ( ) ;
profile - > deleteLater ( ) ;
2016-02-28 15:36:23 +03:00
profile - > rpcClear ( ) ;
2015-07-17 22:17:37 +03:00
profile = 0 ;
}
if ( overview ) {
overview - > hide ( ) ;
overview - > clear ( ) ;
overview - > deleteLater ( ) ;
2016-02-28 15:36:23 +03:00
overview - > rpcClear ( ) ;
2015-07-17 22:17:37 +03:00
overview = 0 ;
}
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 ) {
_topBar . hide ( ) ;
history . hide ( ) ;
2015-10-17 16:52:26 +02:00
if ( ! _a_show . animating ( ) ) {
2015-07-17 22:17:37 +03:00
dialogs . show ( ) ;
if ( ! animCache . isNull ( ) ) {
dialogs . animShow ( animCache ) ;
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 ) {
2014-12-12 19:27:03 +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-02-08 17:54:55 +03:00
if ( Adaptive : : OneColumn ( ) & & ! dialogs . isHidden ( ) ) dialogs . hide ( ) ;
2015-10-17 16:52:26 +02:00
if ( ! _a_show . animating ( ) ) {
2015-07-17 22:17:37 +03:00
if ( history . isHidden ( ) ) history . show ( ) ;
if ( ! animCache . isNull ( ) ) {
history . animShow ( animCache , animTopBarCache , back ) ;
2015-09-16 16:04:08 +03:00
} else 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
2014-12-12 19:27:03 +03:00
if ( ! dialogs . isHidden ( ) ) {
2015-12-07 13:06:59 +03:00
if ( ! back ) {
dialogs . scrollToPeer ( peerId , showAtMsgId ) ;
}
2014-12-12 19:27:03 +03:00
dialogs . update ( ) ;
}
App : : wnd ( ) - > getTitle ( ) - > updateBackButton ( ) ;
2014-05-30 12:53:19 +04: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 ;
}
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 ;
}
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 ( ) {
return history . peer ( ) ;
}
2014-05-30 12:53:19 +04:00
PeerData * MainWidget : : peer ( ) {
2014-11-12 23:18:00 +03:00
return overview ? overview - > peer ( ) : history . peer ( ) ;
2014-05-30 12:53:19 +04:00
}
PeerData * MainWidget : : activePeer ( ) {
2015-07-17 22:17:37 +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 ( ) {
2015-07-17 22:17:37 +03:00
return history . peer ( ) ? history . msgId ( ) : _msgIdInStack ;
2014-07-04 15:12:54 +04:00
}
2014-05-30 12:53:19 +04:00
PeerData * MainWidget : : profilePeer ( ) {
return profile ? profile - > peer ( ) : 0 ;
}
2015-07-03 11:47:16 +03:00
PeerData * MainWidget : : overviewPeer ( ) {
return overview ? overview - > peer ( ) : 0 ;
}
2014-08-21 16:18:56 +04:00
bool MainWidget : : mediaTypeSwitch ( ) {
2015-10-23 21:24:05 +02: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 ( ) ;
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 ;
}
2015-07-03 11:47:16 +03:00
QRect topBarRect = QRect ( _topBar . x ( ) , _topBar . y ( ) , _topBar . width ( ) , st : : topBarHeight ) ;
QRect historyRect = QRect ( history . x ( ) , topBarRect . y ( ) + topBarRect . height ( ) , history . width ( ) , history . y ( ) + history . height ( ) - topBarRect . y ( ) - topBarRect . height ( ) ) ;
QPixmap animCache , animTopBarCache ;
2016-02-08 17:54:55 +03:00
if ( ! _a_show . animating ( ) & & ( Adaptive : : OneColumn ( ) | | profile | | overview | | history . peer ( ) ) ) {
2015-10-17 16:52:26 +02:00
animCache = grabInner ( ) ;
animTopBarCache = grabTopBar ( ) ;
2015-07-03 11:47:16 +03:00
}
2014-08-15 15:19:32 +04:00
if ( ! back ) {
if ( overview ) {
_stack . push_back ( new StackItemOverview ( overview - > peer ( ) , overview - > type ( ) , overview - > lastWidth ( ) , overview - > lastScrollTop ( ) ) ) ;
} else if ( profile ) {
2015-09-06 13:17:09 +03:00
_stack . push_back ( new StackItemProfile ( profile - > peer ( ) , profile - > lastScrollTop ( ) ) ) ;
2015-07-03 11:47:16 +03:00
} else if ( history . peer ( ) ) {
2015-10-14 13:51:37 +02:00
dlgUpdated ( ) ;
2015-07-17 22:17:37 +03:00
_peerInStack = history . peer ( ) ;
_msgIdInStack = history . msgId ( ) ;
2015-10-14 13:51:37 +02:00
dlgUpdated ( ) ;
2015-11-23 18:34:38 +03:00
_stack . push_back ( new StackItemHistory ( _peerInStack , _msgIdInStack , history . replyReturns ( ) ) ) ;
2014-08-15 15:19:32 +04:00
}
}
if ( overview ) {
2014-08-20 09:32:50 +04:00
overview - > hide ( ) ;
2014-08-15 15:19:32 +04:00
overview - > clear ( ) ;
overview - > deleteLater ( ) ;
2016-02-28 15:36:23 +03:00
overview - > rpcClear ( ) ;
2014-08-15 15:19:32 +04:00
}
if ( profile ) {
2014-08-20 09:32:50 +04:00
profile - > hide ( ) ;
2015-06-17 22:43:03 +03:00
profile - > clear ( ) ;
2014-08-15 15:19:32 +04:00
profile - > deleteLater ( ) ;
2016-02-28 15:36:23 +03:00
profile - > rpcClear ( ) ;
2014-08-15 15:19:32 +04:00
profile = 0 ;
}
overview = new OverviewWidget ( this , peer , type ) ;
2014-08-21 16:18:56 +04:00
_mediaTypeMask = 0 ;
2014-08-15 15:19:32 +04:00
_topBar . show ( ) ;
resizeEvent ( 0 ) ;
2015-07-03 11:47:16 +03:00
mediaOverviewUpdated ( peer , type ) ;
if ( ! animCache . isNull ( ) ) {
overview - > animShow ( animCache , animTopBarCache , back , lastScrollTop ) ;
} else {
2015-07-03 13:48:28 +03:00
overview - > fastShow ( ) ;
2015-07-03 11:47:16 +03:00
}
2014-08-15 15:19:32 +04:00
history . animStop ( ) ;
2015-07-17 22:17:37 +03:00
if ( back ) clearBotStartToken ( history . peer ( ) ) ;
2015-11-09 12:51:22 +03:00
history . showHistory ( 0 , 0 ) ;
2014-08-15 15:19:32 +04:00
history . hide ( ) ;
2016-02-08 17:54:55 +03:00
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
}
2015-09-06 13:17:09 +03:00
void MainWidget : : showPeerProfile ( PeerData * peer , bool back , int32 lastScrollTop ) {
2015-11-13 18:14:33 +03:00
if ( peer - > migrateTo ( ) ) {
peer = peer - > migrateTo ( ) ;
}
2014-08-11 13:03:45 +04:00
App : : wnd ( ) - > hideSettings ( ) ;
if ( profile & & profile - > peer ( ) = = peer ) return ;
2015-10-17 16:52:26 +02:00
QPixmap animCache = grabInner ( ) , animTopBarCache = grabTopBar ( ) ;
2014-05-30 12:53:19 +04:00
if ( ! back ) {
2014-08-15 15:19:32 +04:00
if ( overview ) {
_stack . push_back ( new StackItemOverview ( overview - > peer ( ) , overview - > type ( ) , overview - > lastWidth ( ) , overview - > lastScrollTop ( ) ) ) ;
} else if ( profile ) {
2015-09-06 13:17:09 +03:00
_stack . push_back ( new StackItemProfile ( profile - > peer ( ) , profile - > lastScrollTop ( ) ) ) ;
2015-11-19 19:08:46 +03:00
} else if ( history . peer ( ) ) {
2015-10-14 13:51:37 +02:00
dlgUpdated ( ) ;
2015-07-17 22:17:37 +03:00
_peerInStack = history . peer ( ) ;
_msgIdInStack = history . msgId ( ) ;
2015-10-14 13:51:37 +02:00
dlgUpdated ( ) ;
2015-11-23 18:34:38 +03:00
_stack . push_back ( new StackItemHistory ( _peerInStack , _msgIdInStack , history . replyReturns ( ) ) ) ;
2014-05-30 12:53:19 +04:00
}
}
2014-08-15 15:19:32 +04:00
if ( overview ) {
2014-08-20 09:32:50 +04:00
overview - > hide ( ) ;
2014-08-15 15:19:32 +04:00
overview - > clear ( ) ;
overview - > deleteLater ( ) ;
2016-02-28 15:36:23 +03:00
overview - > rpcClear ( ) ;
2014-08-15 15:19:32 +04:00
overview = 0 ;
}
2014-08-01 15:09:46 +04:00
if ( profile ) {
2014-08-20 09:32:50 +04:00
profile - > hide ( ) ;
2015-06-17 22:43:03 +03:00
profile - > clear ( ) ;
2014-08-01 15:09:46 +04:00
profile - > deleteLater ( ) ;
2016-02-28 15:36:23 +03:00
profile - > rpcClear ( ) ;
2014-08-01 15:09:46 +04:00
}
2014-05-30 12:53:19 +04:00
profile = new ProfileWidget ( this , peer ) ;
_topBar . show ( ) ;
resizeEvent ( 0 ) ;
2015-09-06 13:17:09 +03:00
profile - > animShow ( animCache , animTopBarCache , back , lastScrollTop ) ;
2014-05-30 12:53:19 +04:00
history . animStop ( ) ;
2015-07-17 22:17:37 +03:00
if ( back ) clearBotStartToken ( history . peer ( ) ) ;
2015-11-09 12:51:22 +03:00
history . showHistory ( 0 , 0 ) ;
2014-05-30 12:53:19 +04:00
history . hide ( ) ;
2016-02-08 17:54:55 +03:00
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 ( ) ;
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 ) ;
2015-03-24 13:00:27 +03:00
history . setReplyReturns ( histItem - > peer - > id , histItem - > replyReturns ) ;
2014-08-15 15:19:32 +04:00
} else if ( item - > type ( ) = = ProfileStackItem ) {
StackItemProfile * profItem = static_cast < StackItemProfile * > ( item ) ;
2015-09-06 13:17:09 +03:00
showPeerProfile ( profItem - > peer , true , profItem - > lastScrollTop ) ;
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 ( ) {
_topBar . raise ( ) ;
_player . raise ( ) ;
dialogs . raise ( ) ;
_mediaType . raise ( ) ;
if ( _hider ) _hider - > raise ( ) ;
}
2014-05-30 12:53:19 +04:00
QRect MainWidget : : historyRect ( ) const {
QRect r ( history . historyRect ( ) ) ;
r . moveLeft ( r . left ( ) + history . x ( ) ) ;
r . moveTop ( r . top ( ) + history . y ( ) ) ;
return r ;
}
void MainWidget : : dlgUpdated ( DialogRow * row ) {
2015-10-14 13:51:37 +02:00
if ( row ) {
dialogs . dlgUpdated ( row ) ;
} else if ( _peerInStack ) {
dialogs . dlgUpdated ( App : : history ( _peerInStack - > id ) , _msgIdInStack ) ;
}
2014-05-30 12:53:19 +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 ( ) ) {
dialogs . dlgUpdated ( App : : history ( row - > peer - > migrateFrom ( ) - > id ) , - msgId ) ;
} else {
dialogs . dlgUpdated ( row , msgId ) ;
}
2014-05-30 12:53:19 +04:00
}
void MainWidget : : windowShown ( ) {
history . windowShown ( ) ;
}
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 ) ;
2015-06-30 01:09:23 +03:00
App : : emitPeerUpdated ( ) ;
2014-05-30 12:53:19 +04:00
}
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 ) {
history . historyToDown ( hist ) ;
}
void MainWidget : : dialogsToUp ( ) {
dialogs . dialogsToUp ( ) ;
}
2015-03-19 12:18:19 +03:00
void MainWidget : : newUnreadMsg ( History * hist , HistoryItem * item ) {
history . newUnreadMsg ( hist , item ) ;
2014-05-30 12:53:19 +04:00
}
void MainWidget : : historyWasRead ( ) {
history . historyWasRead ( false ) ;
}
2015-06-17 22:43:03 +03:00
void MainWidget : : historyCleared ( History * hist ) {
history . historyCleared ( hist ) ;
}
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
2015-10-17 16:52:26 +02:00
a_coordUnder = back ? anim : : ivalue ( - qFloor ( st : : slideShift * width ( ) ) , 0 ) : anim : : ivalue ( 0 , - qFloor ( st : : slideShift * width ( ) ) ) ;
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 ( ) ) ;
p . drawPixmap ( QRect ( a_coordOver . current ( ) - st : : slideShadow . pxWidth ( ) , 0 , st : : slideShadow . pxWidth ( ) , height ( ) ) , App : : sprite ( ) , st : : slideShadow ) ;
2014-05-30 12:53:19 +04:00
}
}
void MainWidget : : hideAll ( ) {
dialogs . hide ( ) ;
history . hide ( ) ;
if ( profile ) {
profile - > hide ( ) ;
}
2014-08-15 15:19:32 +04:00
if ( overview ) {
overview - > hide ( ) ;
}
2014-05-30 12:53:19 +04:00
_topBar . hide ( ) ;
2014-08-21 16:18:56 +04:00
_mediaType . hide ( ) ;
2015-10-17 10:31:48 +02:00
_player . hide ( ) ;
2015-12-06 19:28:07 +03:00
_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-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 ( ) ) {
dialogs . show ( ) ;
history . hide ( ) ;
if ( overview ) overview - > hide ( ) ;
if ( profile ) profile - > hide ( ) ;
_topBar . hide ( ) ;
} else if ( overview ) {
overview - > show ( ) ;
} else if ( profile ) {
profile - > show ( ) ;
} else if ( history . peer ( ) ) {
history . show ( ) ;
2015-03-24 18:18:20 +03:00
history . resizeEvent ( 0 ) ;
2014-12-12 19:27:03 +03:00
} else {
dialogs . show ( ) ;
history . hide ( ) ;
}
if ( ! selectingPeer ( ) & & ( profile | | overview | | history . peer ( ) ) ) {
_topBar . show ( ) ;
dialogs . hide ( ) ;
}
2016-02-08 17:54:55 +03:00
} else {
if ( _hider ) {
_hider - > show ( ) ;
if ( _forwardConfirm ) {
Ui : : hideLayer ( true ) ;
_forwardConfirm = 0 ;
}
}
dialogs . show ( ) ;
if ( overview ) {
overview - > show ( ) ;
} else if ( profile ) {
profile - > show ( ) ;
} else {
history . show ( ) ;
history . resizeEvent ( 0 ) ;
}
if ( profile | | overview | | history . peer ( ) ) {
_topBar . show ( ) ;
}
2014-05-30 12:53:19 +04:00
}
2015-10-17 10:31:48 +02:00
if ( audioPlayer ( ) ) {
SongMsgId playing ;
AudioPlayerState playingState = AudioPlayerStopped ;
int64 playingPosition = 0 , playingDuration = 0 ;
int32 playingFrequency = 0 ;
audioPlayer ( ) - > currentState ( & playing , & playingState , & playingPosition , & playingDuration , & playingFrequency ) ;
if ( playing ) {
_player . updateState ( playing , playingState , playingPosition , playingDuration , playingFrequency ) ;
if ( ! ( playingState & AudioPlayerStoppedMask ) & & playingState ! = AudioPlayerFinishing ) {
_player . clearSelection ( ) ;
_player . show ( ) ;
_playerHeight = _player . height ( ) ;
}
}
}
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 ) {
int32 tbh = _topBar . isHidden ( ) ? 0 : st : : topBarHeight ;
2016-02-08 17:54:55 +03:00
if ( Adaptive : : OneColumn ( ) ) {
_dialogsWidth = width ( ) ;
_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 ) ;
if ( _hider ) _hider - > setGeometry ( 0 , 0 , _dialogsWidth , height ( ) ) ;
} else {
2016-02-09 19:05:08 +03:00
_dialogsWidth = chatsListWidth ( width ( ) ) ;
2015-10-17 10:31:48 +02:00
dialogs . resize ( _dialogsWidth , height ( ) ) ;
dialogs . moveToLeft ( 0 , 0 ) ;
_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 ) ;
if ( _hider ) {
_hider - > resize ( width ( ) - _dialogsWidth , height ( ) ) ;
_hider - > moveToLeft ( _dialogsWidth , 0 ) ;
}
2014-12-12 19:27:03 +03:00
}
2015-10-17 10:31:48 +02:00
_mediaType . moveToLeft ( width ( ) - _mediaType . width ( ) , _playerHeight + st : : topBarHeight ) ;
2014-05-30 12:53:19 +04:00
if ( profile ) profile - > setGeometry ( history . geometry ( ) ) ;
2014-08-15 15:19:32 +04:00
if ( overview ) overview - > setGeometry ( history . geometry ( ) ) ;
2015-07-03 11:47:16 +03:00
_contentScrollAddToY = 0 ;
}
int32 MainWidget : : contentScrollAddToY ( ) const {
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-02-08 17:54:55 +03:00
_topBar . updateAdaptiveLayout ( ) ;
history . updateAdaptiveLayout ( ) ;
if ( overview ) overview - > updateAdaptiveLayout ( ) ;
if ( profile ) profile - > updateAdaptiveLayout ( ) ;
_player . updateAdaptiveLayout ( ) ;
2014-12-12 19:27:03 +03:00
}
bool MainWidget : : needBackButton ( ) {
return overview | | profile | | ( history . peer ( ) & & history . peer ( ) - > id ) ;
}
2014-05-30 12:53:19 +04:00
void MainWidget : : paintTopBar ( QPainter & p , float64 over , int32 decreaseWidth ) {
if ( profile ) {
profile - > paintTopBar ( p , over , decreaseWidth ) ;
2014-08-15 15:19:32 +04:00
} else if ( overview ) {
overview - > paintTopBar ( p , over , decreaseWidth ) ;
2014-05-30 12:53:19 +04:00
} else {
history . paintTopBar ( p , over , decreaseWidth ) ;
}
}
2014-08-21 16:18:56 +04:00
void MainWidget : : onPhotosSelect ( ) {
if ( overview ) overview - > switchType ( OverviewPhotos ) ;
_mediaType . hideStart ( ) ;
}
void MainWidget : : onVideosSelect ( ) {
if ( overview ) overview - > switchType ( OverviewVideos ) ;
_mediaType . hideStart ( ) ;
}
2015-10-23 21:24:05 +02:00
void MainWidget : : onSongsSelect ( ) {
2016-02-12 19:35:06 +03:00
if ( overview ) overview - > switchType ( OverviewMusicFiles ) ;
2015-10-23 21:24:05 +02:00
_mediaType . hideStart ( ) ;
}
2014-08-21 16:18:56 +04:00
void MainWidget : : onDocumentsSelect ( ) {
2016-02-12 19:35:06 +03:00
if ( overview ) overview - > switchType ( OverviewFiles ) ;
2014-08-21 16:18:56 +04:00
_mediaType . hideStart ( ) ;
}
void MainWidget : : onAudiosSelect ( ) {
2016-02-12 19:35:06 +03:00
if ( overview ) overview - > switchType ( OverviewVoiceFiles ) ;
2014-08-21 16:18:56 +04:00
_mediaType . hideStart ( ) ;
}
2015-08-28 18:15:56 +03:00
void MainWidget : : onLinksSelect ( ) {
if ( overview ) overview - > switchType ( OverviewLinks ) ;
_mediaType . hideStart ( ) ;
}
2014-05-30 12:53:19 +04:00
TopBarWidget * MainWidget : : topBar ( ) {
return & _topBar ;
}
2015-07-03 11:47:16 +03:00
PlayerWidget * MainWidget : : player ( ) {
return & _player ;
}
2014-05-30 12:53:19 +04:00
void MainWidget : : onTopBarClick ( ) {
if ( profile ) {
profile - > topBarClick ( ) ;
2014-08-15 15:19:32 +04:00
} else if ( overview ) {
overview - > topBarClick ( ) ;
2014-05-30 12:53:19 +04:00
} else {
history . topBarClick ( ) ;
}
}
2015-10-03 13:09:09 +03:00
void MainWidget : : onHistoryShown ( History * history , MsgId atMsgId ) {
2016-02-08 17:54:55 +03:00
if ( ( ! Adaptive : : OneColumn ( ) | | ! selectingPeer ( ) ) & & ( profile | | overview | | history ) ) {
2014-05-30 12:53:19 +04:00
_topBar . show ( ) ;
} else {
_topBar . hide ( ) ;
}
resizeEvent ( 0 ) ;
2015-10-17 16:52:26 +02:00
if ( _a_show . animating ( ) ) {
2015-09-01 16:50:56 +03:00
_topBar . hide ( ) ;
}
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 ) {
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 {
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-02-22 14:15:24 +03:00
MTP : : send ( MTPaccount_UpdateNotifySettings ( MTP_inputNotifyPeer ( peer - > input ) , MTP_inputPeerNotifySettings ( MTP_int ( 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 ) {
2014-05-30 12:53:19 +04:00
const QVector < MTPUpdate > & v ( updates . c_vector ( ) . v ) ;
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 ) {
const QVector < MTPUpdate > & v ( updates . c_vector ( ) . v ) ;
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 ) {
if ( MTP : : authedId ( ) ) {
App : : logOut ( ) ;
}
return true ;
}
void MainWidget : : updSetState ( int32 pts , int32 date , int32 qts , int32 seq ) {
2015-09-13 11:41:27 +03:00
if ( pts ) _ptsWaiter . init ( pts ) ;
2014-05-30 12:53:19 +04:00
if ( updDate < date ) 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 : {
const MTPDupdates_channelDifferenceEmpty & d ( diff . c_updates_channelDifferenceEmpty ( ) ) ;
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 : {
const MTPDupdates_channelDifferenceTooLong & d ( diff . c_updates_channelDifferenceTooLong ( ) ) ;
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 ;
if ( unreadCount > = h - > unreadCount ) {
h - > setUnreadCount ( unreadCount , false ) ;
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 ;
}
2015-09-13 11:41:27 +03:00
if ( history . peer ( ) = = channel ) {
history . updateToEndVisibility ( ) ;
2015-09-21 23:57:42 +03:00
history . onListScroll ( ) ;
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 : {
const MTPDupdates_channelDifference & d ( diff . c_updates_channelDifference ( ) ) ;
App : : feedUsers ( d . vusers ) ;
App : : feedChats ( d . vchats , false ) ;
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 ) ;
const QVector < MTPMessage > & vmsgs ( d . vnew_messages . c_vector ( ) . v ) ;
QMap < uint64 , int32 > msgsIds ;
for ( int32 i = 0 , l = vmsgs . size ( ) ; i < l ; + + i ) {
const MTPMessage & msg ( vmsgs . at ( i ) ) ;
switch ( msg . type ( ) ) {
case mtpc_message : {
const MTPDmessage & d ( msg . c_message ( ) ) ;
2015-10-15 02:15:28 +02:00
if ( App : : checkEntitiesAndViewsUpdate ( d ) ) { // new message, index my forwarded messages to links overview, already in blocks
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 ;
}
}
const QVector < MTPUpdate > & vother ( d . vother_updates . c_vector ( ) . v ) ;
for ( int32 i = 0 , l = vother . size ( ) ; i < l ; + + i ) {
if ( vother . at ( i ) . type ( ) = = mtpc_updateChannelGroup ) {
const MTPDupdateChannelGroup & updateGroup ( vother . at ( i ) . c_updateChannelGroup ( ) ) ;
if ( updateGroup . vgroup . type ( ) = = mtpc_messageGroup ) {
const MTPDmessageGroup & group ( updateGroup . vgroup . c_messageGroup ( ) ) ;
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
const MTPMessage & msg ( vmsgs . at ( i . value ( ) - 1 ) ) ;
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
const MTPDupdateChannelGroup & updateGroup ( vother . at ( - i . value ( ) - 1 ) . c_updateChannelGroup ( ) ) ;
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
}
App : : emitPeerUpdated ( ) ;
}
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 : {
const MTPDupdates_channelDifferenceEmpty & d ( diff . c_updates_channelDifferenceEmpty ( ) ) ;
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 : {
const MTPDupdates_channelDifferenceTooLong & d ( diff . c_updates_channelDifferenceTooLong ( ) ) ;
App : : feedUsers ( d . vusers ) ;
App : : feedChats ( d . vchats ) ;
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 : {
const MTPDupdates_channelDifference & d ( diff . c_updates_channelDifference ( ) ) ;
App : : feedUsers ( d . vusers ) ;
App : : feedChats ( d . vchats , false ) ;
_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 ) ;
}
}
App : : emitPeerUpdated ( ) ;
}
2015-09-13 11:41:27 +03:00
bool MainWidget : : failChannelDifference ( ChannelData * channel , const RPCError & error ) {
if ( mtpIsFlood ( error ) ) return false ;
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 ) {
const MTPDupdates_state & d ( state . c_updates_state ( ) ) ;
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
dialogs . loadDialogs ( ) ;
2015-01-26 16:04:41 +03:00
updateOnline ( ) ;
2015-06-30 01:09:23 +03:00
App : : emitPeerUpdated ( ) ;
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 : {
const MTPDupdates_differenceEmpty & 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 ) ;
2015-12-31 23:27:21 +08:00
2015-06-30 01:09:23 +03:00
App : : emitPeerUpdated ( ) ;
2014-05-30 12:53:19 +04:00
} break ;
case mtpc_updates_differenceSlice : {
const MTPDupdates_differenceSlice & d ( diff . c_updates_differenceSlice ( ) ) ;
feedDifference ( d . vusers , d . vchats , d . vnew_messages , d . vother_updates ) ;
const MTPDupdates_state & s ( d . vintermediate_state . c_updates_state ( ) ) ;
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 ( ) ;
2015-06-30 01:09:23 +03:00
App : : emitPeerUpdated ( ) ;
2014-05-30 12:53:19 +04:00
} break ;
case mtpc_updates_difference : {
const MTPDupdates_difference & d ( diff . c_updates_difference ( ) ) ;
feedDifference ( d . vusers , d . vchats , d . vnew_messages , d . vother_updates ) ;
gotState ( d . vstate ) ;
} break ;
} ;
}
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 ( ) ;
2015-06-30 01:09:23 +03:00
App : : feedUsers ( users , false ) ;
App : : feedChats ( chats , false ) ;
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 ) ;
2014-05-30 12:53:19 +04:00
history . peerMessagesUpdated ( ) ;
}
2015-04-04 23:01:34 +03:00
bool MainWidget : : failDifference ( const RPCError & error ) {
2015-09-13 11:41:27 +03:00
if ( mtpIsFlood ( 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 ) ;
history - > lastWidth = 0 ;
history - > lastScrollTop = INT_MAX ;
}
}
}
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 ) ) ;
2016-02-08 17:54:55 +03:00
# ifndef TDESKTOP_DISABLE_AUTOUPDATE
Sandbox : : startUpdateCheck ( ) ;
# endif
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 ( ) ;
2015-03-19 12:18:19 +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 ( ) ) ) ;
2015-06-17 22:43:03 +03:00
} else {
2015-09-06 13:17:09 +03:00
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 ;
if ( peer = = history . peer ( ) ) {
2015-06-19 15:39:33 +03:00
history . updateControlsVisibility ( ) ;
history . resizeEvent ( 0 ) ;
}
}
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 ( ) ;
history . stickersInstalled ( setId ) ;
}
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 ) ;
2015-09-21 23:57:42 +03:00
history . peerMessagesUpdated ( channel - > id ) ;
}
} else if ( h ) {
h - > asChannelHistory ( ) - > checkJoinedMessage ( ) ;
history . peerMessagesUpdated ( channel - > id ) ;
}
}
2015-10-01 17:05:05 +03:00
bool MainWidget : : contentOverlapped ( const QRect & globalRect ) {
return ( history . contentOverlapped ( globalRect ) | |
_mediaType . overlaps ( globalRect ) ) ;
}
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 ;
const MTPDcontacts_resolvedPeer & d ( result . c_contacts_resolvedPeer ( ) ) ;
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 ( ) ) ) ;
2015-06-17 22:43:03 +03:00
} else {
2015-09-06 13:17:09 +03:00
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 ;
2015-09-06 13:17:09 +03:00
if ( peer = = history . peer ( ) ) {
2015-06-19 15:39:33 +03:00
history . updateControlsVisibility ( ) ;
history . resizeEvent ( 0 ) ;
}
}
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 ) {
2015-10-06 22:49:23 +03:00
if ( mtpIsFlood ( 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 : {
const MTPDchatInvite & 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 : {
const MTPDchatInviteAlready & 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 ) {
2015-10-06 22:49:23 +03:00
if ( mtpIsFlood ( 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 ) {
2015-10-06 22:49:23 +03:00
if ( mtpIsFlood ( 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 ( error . type ( ) = = qsl ( " 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 ) {
const QVector < MTPUser > & 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?..
2014-05-30 12:53:19 +04:00
return App : : logOut ( ) ;
}
start ( v [ 0 ] ) ;
}
2015-09-21 23:57:42 +03:00
void MainWidget : : applyNotifySetting ( const MTPNotifyPeer & peer , const MTPPeerNotifySettings & settings , History * h ) {
2015-12-02 20:17:53 +03:00
PeerData * updatePeer = 0 ;
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 : {
const MTPDpeerNotifySettings & d ( settings . c_peerNotifySettings ( ) ) ;
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 ) {
if ( history . peer ( ) = = updatePeer ) {
history . updateNotifySettings ( ) ;
}
dialogs . updateNotifySettings ( updatePeer ) ;
if ( profile & & profile - > peer ( ) = = updatePeer ) {
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 ) {
2015-10-06 22:49:23 +03:00
if ( mtpIsFlood ( 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 ) {
peer - > notify - > flags | = MTPDpeerNotifySettings : : flag_silent ;
} else if ( silent = = SilentNotifiesSetNotify ) {
peer - > notify - > flags & = ~ MTPDpeerNotifySettings : : flag_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
}
2015-09-21 23:57:42 +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
}
StickerSets & sets ( cRefStickerSets ( ) ) ;
for ( StickerSets : : const_iterator i = sets . cbegin ( ) ; i ! = sets . cend ( ) ; + + i ) {
2015-06-28 15:37:10 +03:00
if ( i - > id = = CustomStickerSetId | | i - > id = = DefaultStickerSetId | | ( 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 ) {
StickerSets : : iterator it = sets . find ( CustomStickerSetId ) ;
if ( it = = sets . cend ( ) ) {
2015-06-28 15:37:10 +03:00
it = sets . insert ( CustomStickerSetId , StickerSet ( CustomStickerSetId , 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 ( ) ;
}
2015-01-02 17:55:24 +03:00
history . updateRecentStickers ( ) ;
}
2014-05-30 12:53:19 +04:00
void MainWidget : : activate ( ) {
2015-10-17 16:52:26 +02:00
if ( _a_show . animating ( ) ) return ;
2014-08-15 15:19:32 +04:00
if ( ! profile & & ! 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 {
dialogs . activate ( ) ;
}
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 ) ;
2014-07-18 14:37:34 +04:00
} else if ( history . peer ( ) ) {
history . activate ( ) ;
} else {
dialogs . activate ( ) ;
}
2014-05-30 12:53:19 +04:00
}
}
App : : wnd ( ) - > fixOrder ( ) ;
}
void MainWidget : : destroyData ( ) {
history . destroyData ( ) ;
dialogs . destroyData ( ) ;
}
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 {
2014-08-15 15:19:32 +04:00
return isActive ( ) & & ! profile & & ! 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 {
return dialogs . width ( ) ;
}
MainWidget : : ~ MainWidget ( ) {
2015-11-09 12:51:22 +03:00
if ( App : : main ( ) = = this ) history . showHistory ( 0 , 0 ) ;
2014-11-22 12:45:04 +03:00
2015-02-03 18:02:46 +03:00
delete _background ;
2015-07-17 22:17:37 +03:00
delete _hider ;
2014-05-30 12:53:19 +04:00
MTP : : clearGlobalHandlers ( ) ;
2015-03-19 12:18:19 +03:00
delete _api ;
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 ) ;
}
2015-06-30 01:09:23 +03:00
App : : emitPeerUpdated ( ) ;
} catch ( mtpErrorUnexpected & e ) { // just some other type
2014-11-05 20:43:32 +03:00
}
}
update ( ) ;
}
2014-05-30 12:53:19 +04:00
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 : {
const MTPDupdates & d ( updates . c_updates ( ) ) ;
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
2015-06-30 01:09:23 +03:00
App : : feedUsers ( d . vusers , false ) ;
App : : feedChats ( d . vchats , false ) ;
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 : {
const MTPDupdatesCombined & d ( updates . c_updatesCombined ( ) ) ;
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
2015-06-30 01:09:23 +03:00
App : : feedUsers ( d . vusers , false ) ;
App : : feedChats ( d . vchats , false ) ;
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 : {
const MTPDupdateShort & 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 : {
const MTPDupdateShortMessage & d ( updates . c_updateShortMessage ( ) ) ;
2016-02-18 19:36:33 +03:00
if ( ! App : : userLoaded ( d . vuser_id . v ) | | ( d . has_via_bot_id ( ) & & ! App : : peerLoaded ( peerFromUser ( d . vvia_bot_id ) ) ) ) {
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 ( ) ;
}
2016-02-18 19:36:33 +03:00
if ( d . has_fwd_from ( ) & & d . vfwd_from . type ( ) = = mtpc_messageFwdHeader ) {
const MTPDmessageFwdHeader & f ( d . vfwd_from . c_messageFwdHeader ( ) ) ;
if ( f . has_from_id ( ) & & ! App : : peerLoaded ( peerFromUser ( f . vfrom_id ) ) ) {
MTP_LOG ( 0 , ( " getDifference { good - getting user for updateShortMessage }%1 " ) . arg ( cTestMode ( ) ? " TESTMODE " : " " ) ) ;
return getDifference ( ) ;
}
if ( f . has_channel_id ( ) & & ! App : : peerLoaded ( peerFromChannel ( f . vchannel_id ) ) ) {
MTP_LOG ( 0 , ( " getDifference { good - getting user for updateShortMessage }%1 " ) . arg ( cTestMode ( ) ? " TESTMODE " : " " ) ) ;
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
2015-09-12 14:59:50 +03:00
int32 flags = d . vflags . v | MTPDmessage : : flag_from_id ;
2016-02-18 19:36:33 +03:00
HistoryItem * item = App : : histories ( ) . addNewMessage ( MTP_message ( MTP_int ( 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 ) {
history . peerMessagesUpdated ( item - > history ( ) - > peer - > id ) ;
}
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 : {
const MTPDupdateShortChatMessage & d ( updates . c_updateShortChatMessage ( ) ) ;
2015-05-08 16:06:53 +03:00
bool noFrom = ! App : : userLoaded ( d . vfrom_id . v ) ;
2016-02-18 19:36:33 +03:00
if ( ! App : : chatLoaded ( d . vchat_id . v ) | | noFrom | | ( d . has_via_bot_id ( ) & & ! App : : peerLoaded ( peerFromUser ( d . vvia_bot_id ) ) ) ) {
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 ( ) ;
}
2016-02-18 19:36:33 +03:00
if ( d . has_fwd_from ( ) & & d . vfwd_from . type ( ) = = mtpc_messageFwdHeader ) {
const MTPDmessageFwdHeader & f ( d . vfwd_from . c_messageFwdHeader ( ) ) ;
if ( f . has_from_id ( ) & & ! App : : peerLoaded ( peerFromUser ( f . vfrom_id ) ) ) {
MTP_LOG ( 0 , ( " getDifference { good - getting user for updateShortChatMessage }%1 " ) . arg ( cTestMode ( ) ? " TESTMODE " : " " ) ) ;
return getDifference ( ) ;
}
if ( f . has_channel_id ( ) & & ! App : : peerLoaded ( peerFromChannel ( f . vchannel_id ) ) ) {
MTP_LOG ( 0 , ( " getDifference { good - getting user for updateShortChatMessage }%1 " ) . arg ( cTestMode ( ) ? " TESTMODE " : " " ) ) ;
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
2015-09-12 14:59:50 +03:00
int32 flags = d . vflags . v | MTPDmessage : : flag_from_id ;
2016-02-18 19:36:33 +03:00
HistoryItem * item = App : : histories ( ) . addNewMessage ( MTP_message ( MTP_int ( 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 ) {
history . peerMessagesUpdated ( item - > history ( ) - > peer - > id ) ;
}
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 : {
const MTPDupdateShortSentMessage & d ( updates . c_updateShortSentMessage ( ) ) ;
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 ) {
2015-09-28 17:19:37 +03:00
if ( HistoryItem * item = App : : histItemById ( peerToChannel ( peerId ) , d . vid . v ) ) {
2016-01-09 15:11:23 +08:00
item - > setText ( text , d . has_entities ( ) ? entitiesFromMTP ( d . ventities . c_vector ( ) . v ) : EntitiesInText ( ) ) ;
item - > updateMedia ( d . has_media ( ) ? ( & d . vmedia ) : 0 ) ;
item - > initDimensions ( ) ;
Notify : : historyItemResized ( item ) ;
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 : {
const MTPDupdateNewMessage & 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 ;
2015-09-02 00:33:44 +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 ) {
history . peerMessagesUpdated ( item - > history ( ) - > peer - > id ) ;
}
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 : {
const MTPDupdateMessageID & 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 ) ;
}
2014-05-30 12:53:19 +04: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 : {
const MTPDupdateReadMessagesContents & 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
2015-04-30 16:53:36 +03:00
const QVector < MTPint > & v ( d . vmessages . c_vector ( ) . v ) ;
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 : {
const MTPDupdateReadHistoryInbox & 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 : {
const MTPDupdateReadHistoryOutbox & 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 ) ;
2015-10-03 13:09:09 +03:00
if ( history . peer ( ) & & history . peer ( ) - > id = = id ) {
history . update ( ) ;
}
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 : {
const MTPDupdateWebPage & 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 ) ;
2015-04-07 01:15:29 +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 : {
const MTPDupdateDeleteMessages & 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 ) ;
2014-05-30 12:53:19 +04:00
history . peerMessagesUpdated ( ) ;
2015-09-20 12:54:22 +03:00
ptsApplySkippedUpdates ( ) ;
2014-05-30 12:53:19 +04:00
} break ;
case mtpc_updateUserTyping : {
const MTPDupdateUserTyping & 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 : {
const MTPDupdateChatUserTyping & d ( update . c_updateChatUserTyping ( ) ) ;
2015-09-08 16:34:22 +03:00
History * history = 0 ;
if ( PeerData * chat = App : : peerLoaded ( peerFromChat ( d . vchat_id . v ) ) ) {
history = App : : historyLoaded ( chat - > id ) ;
} else if ( PeerData * channel = App : : peerLoaded ( peerFromChannel ( d . vchat_id . v ) ) ) {
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 : {
const MTPDupdateUserStatus & 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 : {
const MTPDupdateUserName & d ( update . c_updateUserName ( ) ) ;
UserData * user = App : : userLoaded ( d . vuser_id . v ) ;
2014-11-15 02:23:35 +03:00
if ( user ) {
if ( user - > contact < = 0 ) {
user - > setName ( textOneLine ( qs ( d . vfirst_name ) ) , textOneLine ( qs ( d . vlast_name ) ) , user - > nameOrPhone , textOneLine ( qs ( d . vusername ) ) ) ;
} else {
user - > setName ( textOneLine ( user - > firstName ) , textOneLine ( user - > lastName ) , user - > nameOrPhone , textOneLine ( qs ( d . vusername ) ) ) ;
}
2015-06-30 01:09:23 +03:00
App : : markPeerUpdated ( user ) ;
2014-05-30 12:53:19 +04:00
}
} break ;
case mtpc_updateUserPhoto : {
const MTPDupdateUserPhoto & d ( update . c_updateUserPhoto ( ) ) ;
UserData * user = App : : userLoaded ( d . vuser_id . v ) ;
if ( user ) {
user - > setPhoto ( d . vphoto ) ;
user - > photo - > load ( ) ;
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 : {
const MTPDupdateContactRegistered & d ( update . c_updateContactRegistered ( ) ) ;
UserData * user = App : : userLoaded ( d . vuser_id . v ) ;
if ( user ) {
2014-07-04 15:12:54 +04:00
if ( App : : history ( user - > id ) - > loadedAtBottom ( ) ) {
2015-10-28 20:16:52 -04:00
App : : history ( user - > id ) - > addNewService ( clientMsgId ( ) , date ( d . vdate ) , lng_action_user_registered ( lt_from , user - > name ) , MTPDmessage : : flag_unread ) ;
2014-07-04 15:12:54 +04:00
}
2014-05-30 12:53:19 +04:00
}
} break ;
case mtpc_updateContactLink : {
const MTPDupdateContactLink & d ( update . c_updateContactLink ( ) ) ;
2015-06-30 01:09:23 +03:00
App : : feedUserLink ( d . vuser_id , d . vmy_link , d . vforeign_link , false ) ;
2014-05-30 12:53:19 +04:00
} break ;
2014-12-03 16:10:32 +03:00
case mtpc_updateNotifySettings : {
const MTPDupdateNotifySettings & d ( update . c_updateNotifySettings ( ) ) ;
applyNotifySetting ( d . vpeer , d . vnotify_settings ) ;
} break ;
case mtpc_updateDcOptions : {
const MTPDupdateDcOptions & d ( update . c_updateDcOptions ( ) ) ;
MTP : : updateDcOptions ( d . vdc_options . c_vector ( ) . v ) ;
} break ;
case mtpc_updateUserPhone : {
const MTPDupdateUserPhone & d ( update . c_updateUserPhone ( ) ) ;
UserData * user = App : : userLoaded ( d . vuser_id . v ) ;
if ( user ) {
user - > setPhone ( qs ( d . vphone ) ) ;
2015-10-27 20:29:39 -04:00
user - > setName ( 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 : {
const MTPDupdateNewEncryptedMessage & d ( update . c_updateNewEncryptedMessage ( ) ) ;
} break ;
case mtpc_updateEncryptedChatTyping : {
const MTPDupdateEncryptedChatTyping & d ( update . c_updateEncryptedChatTyping ( ) ) ;
} break ;
case mtpc_updateEncryption : {
const MTPDupdateEncryption & d ( update . c_updateEncryption ( ) ) ;
} break ;
case mtpc_updateEncryptedMessagesRead : {
const MTPDupdateEncryptedMessagesRead & d ( update . c_updateEncryptedMessagesRead ( ) ) ;
} break ;
case mtpc_updateUserBlocked : {
const MTPDupdateUserBlocked & 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 : {
const MTPDupdateNewAuthorization & 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 : {
const MTPDupdateServiceNotification & 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 : {
const MTPDupdatePrivacy & 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 : {
const MTPDupdateChannel & 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 : {
const MTPDupdateNewChannelMessage & d ( update . c_updateNewChannelMessage ( ) ) ;
2015-09-20 12:54:22 +03:00
ChannelData * channel = App : : channelLoaded ( peerToChannel ( peerFromMessage ( d . vmessage ) ) ) ;
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 ;
2015-09-06 13:17:09 +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 ) {
history . peerMessagesUpdated ( item - > history ( ) - > peer - > id ) ;
}
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 : {
const MTPDupdateEditChannelMessage & d ( update . c_updateEditChannelMessage ( ) ) ;
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-04 17:34:46 +02:00
case mtpc_updateChannelPinnedMessage : {
const MTPDupdateChannelPinnedMessage & d ( update . c_updateChannelPinnedMessage ( ) ) ;
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 : {
const MTPDupdateReadChannelInbox & 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 : {
const MTPDupdateDeleteChannelMessages & 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 ) ;
2015-09-06 13:17:09 +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 : {
const MTPDupdateChannelTooLong & d ( update . c_updateChannelTooLong ( ) ) ;
2015-09-13 11:41:27 +03:00
if ( ChannelData * channel = App : : channelLoaded ( d . vchannel_id . v ) ) {
getChannelDifference ( channel ) ;
}
} break ;
case mtpc_updateChannelMessageViews : {
const MTPDupdateChannelMessageViews & 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 : {
const MTPDupdateNewStickerSet & d ( update . c_updateNewStickerSet ( ) ) ;
if ( d . vstickerset . type ( ) = = mtpc_messages_stickerSet ) {
const MTPDmessages_stickerSet & set ( d . vstickerset . c_messages_stickerSet ( ) ) ;
if ( set . vset . type ( ) = = mtpc_stickerSet ) {
2016-01-09 20:51:42 +08:00
const MTPDstickerSet & s ( set . vset . c_stickerSet ( ) ) ;
StickerSets & sets ( cRefStickerSets ( ) ) ;
StickerSets : : iterator it = sets . find ( s . vid . v ) ;
if ( it = = sets . cend ( ) ) {
it = sets . insert ( s . vid . v , StickerSet ( s . vid . v , s . vaccess_hash . v , stickerSetTitle ( s ) , qs ( s . vshort_name ) , s . vcount . v , s . vhash . v , s . vflags . v ) ) ;
}
2015-12-02 20:17:53 +03:00
const QVector < MTPDocument > & 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 ( ) ;
const QVector < MTPStickerPack > & packs ( set . vpacks . c_vector ( ) . v ) ;
for ( int32 i = 0 , l = packs . size ( ) ; i < l ; + + i ) {
if ( packs . at ( i ) . type ( ) ! = mtpc_stickerPack ) continue ;
const MTPDstickerPack & pack ( packs . at ( i ) . c_stickerPack ( ) ) ;
if ( EmojiPtr e = emojiGetNoColor ( emojiFromText ( qs ( pack . vemoticon ) ) ) ) {
const QVector < MTPlong > & stickers ( pack . vdocuments . c_vector ( ) . v ) ;
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
StickerSetsOrder & order ( cRefStickerSetsOrder ( ) ) ;
int32 insertAtIndex = 0 , currentIndex = order . indexOf ( s . vid . v ) ;
if ( currentIndex ! = insertAtIndex ) {
if ( currentIndex > 0 ) {
order . removeAt ( currentIndex ) ;
}
order . insert ( insertAtIndex , s . vid . v ) ;
}
StickerSets : : iterator custom = sets . find ( CustomStickerSetId ) ;
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 : {
const MTPDupdateStickerSetsOrder & d ( update . c_updateStickerSetsOrder ( ) ) ;
const QVector < MTPlong > & order ( d . vorder . c_vector ( ) . v ) ;
const StickerSets & sets ( cStickerSets ( ) ) ;
StickerSetsOrder result ;
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 ) ;
}
if ( result . size ( ) ! = cStickerSetsOrder ( ) . size ( ) | | result . size ( ) ! = order . size ( ) ) {
cSetLastStickersUpdate ( 0 ) ;
App : : main ( ) - > updateStickers ( ) ;
} else {
cSetStickerSetsOrder ( result ) ;
Local : : writeStickers ( ) ;
emit stickersUpdated ( ) ;
}
} break ;
case mtpc_updateStickerSets : {
cSetLastStickersUpdate ( 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
}
}