mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-02-20 15:17:41 +00:00
channels members and admins management done
This commit is contained in:
parent
d54f299327
commit
9154edc217
@ -28,19 +28,21 @@ if exist ..\Win32\Deploy\deploy\%AppVersionStrMajor%\%AppVersionStr%\ goto error
|
||||
if exist ..\Win32\Deploy\deploy\%AppVersionStrMajor%\%AppVersionStr%.dev\ goto error_exist2
|
||||
if exist ..\Win32\Deploy\tupdate%AppVersion% goto error_exist3
|
||||
|
||||
copy ./SourceFiles/telegram.qrc /B+ ,,/Y
|
||||
cd SourceFiles\
|
||||
copy telegram.qrc /B+,,/Y
|
||||
cd ..\
|
||||
if %errorlevel% neq 0 goto error
|
||||
|
||||
cd ..\
|
||||
MSBuild Telegram.sln /property:Configuration=Deploy
|
||||
if %errorlevel% neq 0 goto error
|
||||
if %errorlevel% neq 0 goto error0
|
||||
|
||||
echo .
|
||||
echo Version %AppVersionStr%%DevPostfix% build successfull! Preparing..
|
||||
echo .
|
||||
|
||||
set "PATH=%PATH%;C:\Program Files\7-Zip;C:\Program Files (x86)\Inno Setup 5"
|
||||
cd ..\Win32\Deploy
|
||||
cd Win32\Deploy\
|
||||
|
||||
call ..\..\..\TelegramPrivate\Sign.bat Telegram.exe
|
||||
if %errorlevel% neq 0 goto error1
|
||||
@ -71,7 +73,7 @@ move tsetup.%AppVersionStr%%DevPostfix%.exe deploy\%AppVersionStrMajor%\%AppVers
|
||||
move tupdate%AppVersion% deploy\%AppVersionStrMajor%\%AppVersionStr%%DevPostfix%\
|
||||
if %errorlevel% neq 0 goto error1
|
||||
|
||||
cd deploy\%AppVersionStrMajor%\%AppVersionStr%%DevPostfix%
|
||||
cd deploy\%AppVersionStrMajor%\%AppVersionStr%%DevPostfix%\
|
||||
7z a -mx9 tportable.%AppVersionStr%%DevPostfix%.zip Telegram\
|
||||
if %errorlevel% neq 0 goto error2
|
||||
|
||||
@ -97,13 +99,15 @@ xcopy Updater.pdb Z:\TBuild\tother\tsetup\%AppVersionStrMajor%\%AppVersionStr%%D
|
||||
|
||||
echo Version %AppVersionStr%%DevPostfix% deployed successfully!
|
||||
|
||||
cd ..\..\..\..\..\Telegram
|
||||
cd ..\..\..\..\..\Telegram\
|
||||
goto eof
|
||||
|
||||
:error2
|
||||
cd ..\..\..
|
||||
cd ..\..\..\
|
||||
:error1
|
||||
cd ..\..\Telegram
|
||||
cd ..\..\
|
||||
:error0
|
||||
cd Telegram\
|
||||
goto error
|
||||
|
||||
:error_exist1
|
||||
|
@ -95,6 +95,9 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_channel_status" = "channel";
|
||||
|
||||
"lng_channel_members_link" = "{count:_not_used_|# member|# members} »";
|
||||
"lng_channel_admins_link" = "{count:_not_used_|# administrator|# administrators} »";
|
||||
|
||||
"lng_server_error" = "Internal server error.";
|
||||
"lng_flood_error" = "Too many tries. Please try again later.";
|
||||
"lng_deleted" = "Unknown";
|
||||
@ -354,12 +357,13 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_profile_chat_unaccessible" = "Group is unaccessible";
|
||||
"lng_topbar_info" = "Info";
|
||||
"lng_profile_about_section" = "About";
|
||||
"lng_profile_description_section" = "Description";
|
||||
"lng_profile_settings_section" = "Settings";
|
||||
"lng_profile_actions_section" = "Actions";
|
||||
"lng_profile_bot_settings" = "Settings";
|
||||
"lng_profile_bot_help" = "Help";
|
||||
"lng_profile_create_public_link" = "Create public link";
|
||||
"lng_profile_edit_public_link" = "Edit link";
|
||||
"lng_profile_edit_public_link" = "Edit public link";
|
||||
"lng_profile_participants_section" = "Members";
|
||||
"lng_profile_info" = "Contact info";
|
||||
"lng_profile_group_info" = "Group info";
|
||||
@ -384,8 +388,10 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_profile_set_group_photo" = "Set Photo";
|
||||
"lng_profile_add_participant" = "Add Members";
|
||||
"lng_profile_delete_and_exit" = "Leave";
|
||||
"lng_profile_kick" = "Kick";
|
||||
"lng_profile_sure_kick" = "Kick {user} from the group?";
|
||||
"lng_profile_kick" = "Remove";
|
||||
"lng_profile_sure_kick" = "Remove {user} from the group?";
|
||||
"lng_profile_sure_kick_channel" = "Remove {user} from the channel?";
|
||||
"lng_profile_sure_kick_admin" = "Remove {user} from administrators?";
|
||||
"lng_profile_loading" = "Loading..";
|
||||
"lng_profile_shared_media" = "Shared media";
|
||||
"lng_profile_no_media" = "No media in this conversation.";
|
||||
@ -402,13 +408,20 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_profile_audio_files_header" = "Playlist";
|
||||
"lng_profile_copy_phone" = "Copy phone number";
|
||||
|
||||
"lng_channel_add_admins" = "Add";
|
||||
"lng_channel_members" = "Members";
|
||||
"lng_channel_admins" = "Administrators";
|
||||
"lng_channel_add_admin" = "Add Administrator";
|
||||
"lng_channel_admin_sure" = "Add {user} to administrators?";
|
||||
|
||||
"lng_participant_filter" = "Search";
|
||||
"lng_participant_invite" = "Invite";
|
||||
"lng_participant_invite_sorry" = "Sorry, you can only add the first\n{count} members to a channel personally.\n\nFrom now on, people will need\nto join via your invite link.";
|
||||
"lng_create_group_back" = "Back";
|
||||
"lng_create_group_next" = "Next";
|
||||
"lng_create_group_create" = "Create";
|
||||
"lng_create_group_title" = "New Group";
|
||||
"lng_create_group_about" = "Groups have up to 200 members and are good for smaller communities";
|
||||
"lng_create_group_about" = "Groups have up to {count} members and are good for smaller communities";
|
||||
"lng_create_channel_title" = "New Channel";
|
||||
"lng_create_channel_about" = "Channels have unlimited number of members and are good for connecting with large audiences";
|
||||
"lng_create_public_channel_title" = "Public Channel";
|
||||
@ -476,7 +489,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_group_invite_want_join_channel" = "Do you want to join channel «{title}»?";
|
||||
"lng_group_invite_join" = "Join";
|
||||
|
||||
"lng_group_invite_link" = "Invite link";
|
||||
"lng_group_invite_link" = "Invite link:";
|
||||
"lng_group_invite_create" = "Create an invite link";
|
||||
"lng_group_invite_about" = "Telegram users will be able to join\nyour group by following this link.";
|
||||
"lng_channel_invite_about" = "Telegram users will be able to join\nyour channel by following this link.";
|
||||
@ -731,6 +744,8 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_menu_insert_unicode" = "Insert Unicode control character";
|
||||
|
||||
"lng_full_name" = "{first_name} {last_name}";
|
||||
|
||||
// Wnd specific
|
||||
|
||||
"lng_wnd_choose_program_menu" = "Choose Default Program...";
|
||||
|
@ -1293,7 +1293,7 @@ profileNameFont: font(20px);
|
||||
profileStatusLeft: 22px;
|
||||
profileStatusTop: 31px;
|
||||
profileStatusFont: font(fsize);
|
||||
profilePhoneLeft: 20px;
|
||||
profilePhoneLeft: 22px;
|
||||
profilePhoneTop: 62px;
|
||||
profilePhoneFont: font(16px);
|
||||
profileButtonTop: 18px;
|
||||
@ -1332,6 +1332,8 @@ btnShareContact: flatButton(btnDefNext, btnDefBig) {
|
||||
}
|
||||
profileMinBtnPadding: 10px;
|
||||
|
||||
membersPadding: margins(0px, 10px, 0px, 10px);
|
||||
|
||||
forwardWidth: 364px;
|
||||
forwardMargins: margins(30px, 10px, 30px, 10px);
|
||||
forwardFont: font(16px);
|
||||
@ -1462,6 +1464,7 @@ newGroupPhoto: flatButton(btnDefNext, btnDefBig) {
|
||||
newGroupPhotoSize: 96px;
|
||||
newGroupPhotoSkip: 18px;
|
||||
newGroupDescriptionSkip: 28px;
|
||||
newGroupPublicLinkSkip: 27px;
|
||||
newGroupDescription: flatTextarea(taDefFlat) {
|
||||
font: font(15px);
|
||||
bgColor: transparent;
|
||||
@ -1832,7 +1835,7 @@ stickerPanSize: size(64px, 64px);
|
||||
stickerPanPadding: 11px;
|
||||
stickerPanDelete: sprite(128px, 132px, 12px, 12px);
|
||||
stickerPanDeleteOpacity: 0.5;
|
||||
stickerIconPadding: 3px;
|
||||
stickerIconPadding: 5px;
|
||||
stickerIconOpacity: 0.7;
|
||||
stickerIconSel: 2px;
|
||||
stickerIconSelColor: #58b2ed;
|
||||
@ -1841,6 +1844,12 @@ stickerIconLeft: sprite(342px, 72px, 40px, 1px);
|
||||
stickerIconRight: sprite(342px, 73px, 40px, 1px);
|
||||
stickerIconMove: 400;
|
||||
|
||||
verifiedCheckProfile: sprite(285px, 240px, 22px, 22px);
|
||||
verifiedCheckProfilePos: point(9px, 4px);
|
||||
verifiedCheck: sprite(285px, 221px, 19px, 19px);
|
||||
verifiedCheckInv: sprite(304px, 221px, 19px, 19px);
|
||||
verifiedCheckPos: point(5px, 0px);
|
||||
|
||||
botKbDuration: 200;
|
||||
botKbBg: #f7f7f7;
|
||||
botKbOverBg: #e8ecef;
|
||||
|
@ -252,7 +252,7 @@ bool update() {
|
||||
if (copyResult == FALSE) {
|
||||
writeLog(L"Error: failed to copy, asking to retry..");
|
||||
WCHAR errMsg[2048];
|
||||
wsprintf(errMsg, L"Failed to update Telegram :(\n%s is not accessible.", tofname);
|
||||
wsprintf(errMsg, L"Failed to update Telegram :(\n%s is not accessible.", tofname.c_str());
|
||||
if (MessageBox(0, errMsg, L"Update error!", MB_ICONERROR | MB_RETRYCANCEL) != IDRETRY) {
|
||||
delFolder();
|
||||
return false;
|
||||
|
@ -276,10 +276,11 @@ void ApiWrap::gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result) {
|
||||
}
|
||||
channel->about = qs(f.vabout);
|
||||
channel->count = f.has_participants_count() ? f.vparticipants_count.v : 0;
|
||||
channel->adminsCount = f.has_admins_count() ? f.vadmins_count.v : 0;
|
||||
channel->invitationUrl = (f.vexported_invite.type() == mtpc_chatInviteExported) ? qs(f.vexported_invite.c_chatInviteExported().vlink) : QString();
|
||||
if (History *h = App::historyLoaded(channel->id)) {
|
||||
if (h->inboxReadBefore < f.vread_inbox_max_id.v + 1) {
|
||||
h->unreadCount = f.vunread_important_count.v;
|
||||
h->setUnreadCount(f.vunread_important_count.v);
|
||||
h->inboxReadBefore = f.vread_inbox_max_id.v + 1;
|
||||
h->asChannelHistory()->unreadCountAll = f.vunread_count.v;
|
||||
}
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 172 KiB After Width: | Height: | Size: 174 KiB |
Binary file not shown.
Before Width: | Height: | Size: 230 KiB After Width: | Height: | Size: 233 KiB |
@ -2291,11 +2291,11 @@ public:
|
||||
trySet(_performer, dict, "artist");
|
||||
trySet(_performer, dict, "performer");
|
||||
trySet(_performer, dict, "album_artist");
|
||||
for (AVDictionaryEntry *tag = av_dict_get(dict, "", 0, AV_DICT_IGNORE_SUFFIX); tag; tag = av_dict_get(dict, "", tag, AV_DICT_IGNORE_SUFFIX)) {
|
||||
const char *key = tag->key;
|
||||
const char *value = tag->value;
|
||||
QString tmp = QString::fromUtf8(value);
|
||||
}
|
||||
//for (AVDictionaryEntry *tag = av_dict_get(dict, "", 0, AV_DICT_IGNORE_SUFFIX); tag; tag = av_dict_get(dict, "", tag, AV_DICT_IGNORE_SUFFIX)) {
|
||||
// const char *key = tag->key;
|
||||
// const char *value = tag->value;
|
||||
// QString tmp = QString::fromUtf8(value);
|
||||
//}
|
||||
}
|
||||
|
||||
int64 duration() {
|
||||
|
@ -20,6 +20,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
|
||||
#include "application.h"
|
||||
#include "addcontactbox.h"
|
||||
#include "contactsbox.h"
|
||||
#include "mainwidget.h"
|
||||
#include "window.h"
|
||||
|
||||
@ -31,6 +32,7 @@ AddContactBox::AddContactBox(QString fname, QString lname, QString phone) :
|
||||
_firstInput(this, st::inpAddContact, lang(lng_signup_firstname), fname),
|
||||
_lastInput(this, st::inpAddContact, lang(lng_signup_lastname), lname),
|
||||
_phoneInput(this, st::inpAddContact, lang(lng_contact_phone), phone.isEmpty() ? phone : App::formatPhone(phone)),
|
||||
_invertOrder(langFirstNameGoesSecond()),
|
||||
_contactId(0), _addRequest(0) {
|
||||
|
||||
if (!phone.isEmpty()) {
|
||||
@ -48,12 +50,16 @@ AddContactBox::AddContactBox(PeerData *peer) :
|
||||
_firstInput(this, st::inpAddContact, lang(peer->isUser() ? lng_signup_firstname : lng_dlg_new_group_name), peer->isUser() ? peer->asUser()->firstName : peer->name),
|
||||
_lastInput(this, st::inpAddContact, lang(lng_signup_lastname), peer->isUser() ? peer->asUser()->lastName : QString()),
|
||||
_phoneInput(this, st::inpAddContact, lang(lng_contact_phone)),
|
||||
_invertOrder((!peer || !peer->isChat()) && langFirstNameGoesSecond()),
|
||||
_contactId(0), _addRequest(0) {
|
||||
|
||||
initBox();
|
||||
}
|
||||
|
||||
void AddContactBox::initBox() {
|
||||
if (_invertOrder) {
|
||||
setTabOrder(&_lastInput, &_firstInput);
|
||||
}
|
||||
if (_peer) {
|
||||
if (_peer->isUser()) {
|
||||
_boxTitle = lang(_peer == App::self() ? lng_edit_self_title : lng_edit_contact_title);
|
||||
@ -61,10 +67,6 @@ void AddContactBox::initBox() {
|
||||
} else if (_peer->isChat()) {
|
||||
_boxTitle = lang(lng_edit_group_title);
|
||||
setMaxHeight(st::boxTitleHeight + st::addContactPadding.top() + 1 * _firstInput.height() + st::addContactPadding.bottom() + _addButton.height());
|
||||
} else if (_peer->isChannel()) {
|
||||
// CHANNELS_UX
|
||||
_boxTitle = lang(lng_edit_channel_title);
|
||||
setMaxHeight(st::boxTitleHeight + st::addContactPadding.top() + 1 * _firstInput.height() + st::addContactPadding.bottom() + _addButton.height());
|
||||
}
|
||||
} else {
|
||||
bool readyToAdd = !_phoneInput.text().isEmpty() && (!_firstInput.text().isEmpty() || !_lastInput.text().isEmpty());
|
||||
@ -107,7 +109,7 @@ void AddContactBox::showAll() {
|
||||
|
||||
void AddContactBox::showDone() {
|
||||
if ((_firstInput.text().isEmpty() && _lastInput.text().isEmpty()) || _phoneInput.isHidden() || !_phoneInput.isEnabled()) {
|
||||
_firstInput.setFocus();
|
||||
(_invertOrder ? _lastInput : _firstInput).setFocus();
|
||||
} else {
|
||||
_phoneInput.setFocus();
|
||||
}
|
||||
@ -180,9 +182,15 @@ void AddContactBox::paintEvent(QPaintEvent *e) {
|
||||
}
|
||||
|
||||
void AddContactBox::resizeEvent(QResizeEvent *e) {
|
||||
_firstInput.setGeometry(st::addContactPadding.left(), st::boxTitleHeight + st::addContactPadding.top(), width() - st::addContactPadding.left() - st::addContactPadding.right(), _firstInput.height());
|
||||
_lastInput.setGeometry(st::addContactPadding.left(), _firstInput.y() + _firstInput.height() + st::addContactDelta, _firstInput.width(), _firstInput.height());
|
||||
_phoneInput.setGeometry(st::addContactPadding.left(), _lastInput.y() + _lastInput.height() + st::addContactDelta, _lastInput.width(), _lastInput.height());
|
||||
if (_invertOrder) {
|
||||
_lastInput.setGeometry(st::addContactPadding.left(), st::boxTitleHeight + st::addContactPadding.top(), width() - st::addContactPadding.left() - st::addContactPadding.right(), _lastInput.height());
|
||||
_firstInput.setGeometry(st::addContactPadding.left(), _lastInput.y() + _lastInput.height() + st::addContactDelta, _lastInput.width(), _lastInput.height());
|
||||
_phoneInput.setGeometry(st::addContactPadding.left(), _firstInput.y() + _firstInput.height() + st::addContactDelta, _lastInput.width(), _lastInput.height());
|
||||
} else {
|
||||
_firstInput.setGeometry(st::addContactPadding.left(), st::boxTitleHeight + st::addContactPadding.top(), width() - st::addContactPadding.left() - st::addContactPadding.right(), _firstInput.height());
|
||||
_lastInput.setGeometry(st::addContactPadding.left(), _firstInput.y() + _firstInput.height() + st::addContactDelta, _firstInput.width(), _firstInput.height());
|
||||
_phoneInput.setGeometry(st::addContactPadding.left(), _lastInput.y() + _lastInput.height() + st::addContactDelta, _lastInput.width(), _lastInput.height());
|
||||
}
|
||||
|
||||
_cancelButton.move(0, height() - _cancelButton.height());
|
||||
_addButton.move(width() - _addButton.width(), height() - _addButton.height());
|
||||
@ -194,8 +202,13 @@ void AddContactBox::onSend() {
|
||||
|
||||
QString firstName = _firstInput.text().trimmed(), lastName = _lastInput.text().trimmed(), phone = _phoneInput.text().trimmed();
|
||||
if (firstName.isEmpty() && lastName.isEmpty()) {
|
||||
_firstInput.setFocus();
|
||||
_firstInput.notaBene();
|
||||
if (_invertOrder) {
|
||||
_lastInput.setFocus();
|
||||
_lastInput.notaBene();
|
||||
} else {
|
||||
_firstInput.setFocus();
|
||||
_firstInput.notaBene();
|
||||
}
|
||||
return;
|
||||
} else if (!_peer && !App::isValidPhone(phone)) {
|
||||
_phoneInput.setFocus();
|
||||
@ -212,8 +225,6 @@ void AddContactBox::onSend() {
|
||||
} else if (_peer) {
|
||||
if (_peer->isChat()) {
|
||||
_addRequest = MTP::send(MTPmessages_EditChatTitle(_peer->asChat()->inputChat, MTP_string(firstName)), rpcDone(&AddContactBox::onSaveChatDone), rpcFail(&AddContactBox::onSaveFail));
|
||||
} else if (_peer->isChannel()) {
|
||||
_addRequest = MTP::send(MTPchannels_EditTitle(_peer->asChannel()->inputChannel, MTP_string(firstName)), rpcDone(&AddContactBox::onSaveChatDone), rpcFail(&AddContactBox::onSaveFail));
|
||||
} else {
|
||||
_contactId = MTP::nonce<uint64>();
|
||||
QVector<MTPInputContact> v(1, MTP_inputPhoneContact(MTP_long(_contactId), MTP_string(_peer->asUser()->phone), MTP_string(firstName), MTP_string(lastName)));
|
||||
@ -345,11 +356,14 @@ a_descriptionBg(st::newGroupName.bgColor->c, st::newGroupName.bgColor->c),
|
||||
a_descriptionBorder(st::newGroupName.borderColor->c, st::newGroupName.borderColor->c),
|
||||
a_description(animFunc(this, &EditChannelBox::descriptionAnimStep)),
|
||||
_description(this, st::newGroupDescription, lang(lng_create_group_description), _channel->about),
|
||||
_publicLink(this, lang(channel->isPublic() ? lng_profile_edit_public_link : lng_profile_create_public_link)),
|
||||
_saveTitleRequestId(0), _saveDescriptionRequestId(0) {
|
||||
_boxTitle = lang(lng_edit_channel_title);
|
||||
|
||||
_description.installEventFilter(this);
|
||||
|
||||
connect(App::main(), SIGNAL(peerNameChanged(PeerData*, const PeerData::Names&, const PeerData::NameFirstChars&)), this, SLOT(peerUpdated(PeerData*)));
|
||||
|
||||
setMouseTracking(true);
|
||||
|
||||
_description.resize(width() - st::newGroupPadding.left() - st::newGroupPadding.right() - st::newGroupDescriptionPadding.left() - st::newGroupDescriptionPadding.right(), _title.height() - st::newGroupDescriptionPadding.top() - st::newGroupDescriptionPadding.bottom());
|
||||
@ -365,6 +379,8 @@ _saveTitleRequestId(0), _saveDescriptionRequestId(0) {
|
||||
connect(&_saveButton, SIGNAL(clicked()), this, SLOT(onSave()));
|
||||
connect(&_cancelButton, SIGNAL(clicked()), this, SLOT(onClose()));
|
||||
|
||||
connect(&_publicLink, SIGNAL(clicked()), this, SLOT(onPublicLink()));
|
||||
|
||||
prepare();
|
||||
}
|
||||
|
||||
@ -373,6 +389,7 @@ void EditChannelBox::hideAll() {
|
||||
_description.hide();
|
||||
_saveButton.hide();
|
||||
_cancelButton.hide();
|
||||
_publicLink.hide();
|
||||
}
|
||||
|
||||
void EditChannelBox::showAll() {
|
||||
@ -380,6 +397,7 @@ void EditChannelBox::showAll() {
|
||||
_description.show();
|
||||
_saveButton.show();
|
||||
_cancelButton.show();
|
||||
_publicLink.show();
|
||||
}
|
||||
|
||||
void EditChannelBox::showDone() {
|
||||
@ -439,6 +457,12 @@ bool EditChannelBox::descriptionAnimStep(float64 ms) {
|
||||
return res;
|
||||
}
|
||||
|
||||
void EditChannelBox::peerUpdated(PeerData *peer) {
|
||||
if (peer == _channel) {
|
||||
_publicLink.setText(lang(_channel->isPublic() ? lng_profile_edit_public_link : lng_profile_create_public_link));
|
||||
}
|
||||
}
|
||||
|
||||
void EditChannelBox::onDescriptionResized() {
|
||||
updateMaxHeight();
|
||||
update();
|
||||
@ -449,8 +473,10 @@ QRect EditChannelBox::descriptionRect() const {
|
||||
}
|
||||
|
||||
void EditChannelBox::updateMaxHeight() {
|
||||
int32 h = st::boxTitleHeight + st::newGroupPadding.top() + _title.height() + st::newGroupPadding.bottom() + _saveButton.height();
|
||||
int32 h = st::boxTitleHeight + st::newGroupPadding.top() + _title.height();
|
||||
h += st::newGroupDescriptionSkip + st::newGroupDescriptionPadding.top() + _description.height() + st::newGroupDescriptionPadding.bottom();
|
||||
h += st::newGroupPublicLinkSkip + _publicLink.height();
|
||||
h += st::newGroupPadding.bottom() + _saveButton.height();
|
||||
setMaxHeight(h);
|
||||
}
|
||||
|
||||
@ -475,8 +501,9 @@ void EditChannelBox::resizeEvent(QResizeEvent *e) {
|
||||
|
||||
_description.moveToLeft(st::newGroupPadding.left() + st::newGroupDescriptionPadding.left(), _title.y() + _title.height() + st::newGroupDescriptionSkip + st::newGroupDescriptionPadding.top(), width());
|
||||
|
||||
int32 buttonTop = _description.y() + _description.height() + st::newGroupDescriptionPadding.bottom();
|
||||
buttonTop += st::newGroupPadding.bottom();
|
||||
_publicLink.moveToLeft(st::newGroupPadding.left(), _description.y() + _description.height() + st::newGroupDescriptionPadding.bottom() + st::newGroupPublicLinkSkip, width());
|
||||
|
||||
int32 buttonTop = _publicLink.y() + _publicLink.height() + st::newGroupPadding.bottom();
|
||||
_cancelButton.move(0, buttonTop);
|
||||
_saveButton.move(width() - _saveButton.width(), buttonTop);
|
||||
}
|
||||
@ -521,6 +548,10 @@ void EditChannelBox::onSave() {
|
||||
_saveTitleRequestId = MTP::send(MTPchannels_EditTitle(_channel->inputChannel, MTP_string(_sentTitle)), rpcDone(&EditChannelBox::onSaveTitleDone), rpcFail(&EditChannelBox::onSaveFail));
|
||||
}
|
||||
|
||||
void EditChannelBox::onPublicLink() {
|
||||
App::wnd()->replaceLayer(new SetupChannelBox(_channel, true));
|
||||
}
|
||||
|
||||
void EditChannelBox::saveDescription() {
|
||||
_saveDescriptionRequestId = MTP::send(MTPchannels_EditAbout(_channel->inputChannel, MTP_string(_sentDescription)), rpcDone(&EditChannelBox::onSaveDescriptionDone), rpcFail(&EditChannelBox::onSaveFail));
|
||||
}
|
||||
|
@ -64,6 +64,8 @@ private:
|
||||
FlatButton _addButton, _retryButton, _cancelButton;
|
||||
FlatInput _firstInput, _lastInput, _phoneInput;
|
||||
|
||||
bool _invertOrder;
|
||||
|
||||
uint64 _contactId;
|
||||
|
||||
mtpRequestId _addRequest;
|
||||
@ -95,8 +97,11 @@ public:
|
||||
|
||||
public slots:
|
||||
|
||||
void peerUpdated(PeerData *peer);
|
||||
|
||||
void onSave();
|
||||
void onDescriptionResized();
|
||||
void onPublicLink();
|
||||
|
||||
protected:
|
||||
|
||||
@ -127,6 +132,8 @@ private:
|
||||
Animation a_description;
|
||||
FlatTextarea _description;
|
||||
|
||||
LinkButton _publicLink;
|
||||
|
||||
mtpRequestId _saveTitleRequestId, _saveDescriptionRequestId;
|
||||
QString _sentTitle, _sentDescription;
|
||||
};
|
||||
|
@ -22,6 +22,8 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
#include "mainwidget.h"
|
||||
#include "window.h"
|
||||
|
||||
#include "application.h"
|
||||
|
||||
TextParseOptions _confirmBoxTextOptions = {
|
||||
TextParseLinks | TextParseMultiline | TextParseRichText, // flags
|
||||
0, // maxw
|
||||
@ -195,3 +197,97 @@ void ConfirmLinkBox::onOpenLink() {
|
||||
}
|
||||
App::wnd()->hideLayer();
|
||||
}
|
||||
|
||||
MaxInviteBox::MaxInviteBox(const QString &link) :
|
||||
_close(this, lang(lng_close), st::btnInfoClose),
|
||||
_text(st::boxFont, lng_participant_invite_sorry(lt_count, QString::number(cMaxGroupCount())), _confirmBoxTextOptions),
|
||||
_link(link), _linkOver(false),
|
||||
a_goodOpacity(0, 0), a_good(animFunc(this, &MaxInviteBox::goodAnimStep)) {
|
||||
setMouseTracking(true);
|
||||
|
||||
_textWidth = st::boxWidth + 10 - st::boxPadding.left() - st::boxPadding.right();
|
||||
_textHeight = qMin(_text.countHeight(_textWidth), 16 * st::boxFont->height);
|
||||
setMaxHeight(st::boxPadding.top() + _textHeight + st::newGroupLinkPadding.top() + st::newGroupLink.height + st::newGroupLinkPadding.bottom() + _close.height());
|
||||
|
||||
connect(&_close, SIGNAL(clicked()), this, SLOT(onClose()));
|
||||
|
||||
prepare();
|
||||
}
|
||||
|
||||
void MaxInviteBox::mouseMoveEvent(QMouseEvent *e) {
|
||||
updateSelected(e->globalPos());
|
||||
}
|
||||
|
||||
void MaxInviteBox::mousePressEvent(QMouseEvent *e) {
|
||||
mouseMoveEvent(e);
|
||||
if (_linkOver) {
|
||||
App::app()->clipboard()->setText(_link);
|
||||
_goodTextLink = lang(lng_create_channel_link_copied);
|
||||
a_goodOpacity = anim::fvalue(1, 0);
|
||||
a_good.start();
|
||||
}
|
||||
}
|
||||
|
||||
void MaxInviteBox::leaveEvent(QEvent *e) {
|
||||
updateSelected(QCursor::pos());
|
||||
}
|
||||
|
||||
void MaxInviteBox::updateSelected(const QPoint &cursorGlobalPosition) {
|
||||
QPoint p(mapFromGlobal(cursorGlobalPosition));
|
||||
|
||||
bool linkOver = _invitationLink.contains(p);
|
||||
if (linkOver != _linkOver) {
|
||||
_linkOver = linkOver;
|
||||
update();
|
||||
setCursor(_linkOver ? style::cur_pointer : style::cur_default);
|
||||
}
|
||||
}
|
||||
|
||||
bool MaxInviteBox::goodAnimStep(float64 ms) {
|
||||
float dt = ms / st::newGroupLinkFadeDuration;
|
||||
bool res = true;
|
||||
if (dt >= 1) {
|
||||
res = false;
|
||||
a_goodOpacity.finish();
|
||||
} else {
|
||||
a_goodOpacity.update(dt, anim::linear);
|
||||
}
|
||||
update();
|
||||
return res;
|
||||
}
|
||||
|
||||
void MaxInviteBox::hideAll() {
|
||||
_close.hide();
|
||||
}
|
||||
|
||||
void MaxInviteBox::showAll() {
|
||||
_close.show();
|
||||
}
|
||||
|
||||
void MaxInviteBox::paintEvent(QPaintEvent *e) {
|
||||
Painter p(this);
|
||||
if (paint(p)) return;
|
||||
|
||||
// draw box title / text
|
||||
p.setFont(st::boxFont->f);
|
||||
p.setPen(st::black->p);
|
||||
_text.drawElided(p, st::boxPadding.left(), st::boxPadding.top(), _textWidth, 16, (_text.maxWidth() < width()) ? style::al_center : style::al_left);
|
||||
|
||||
QTextOption option(style::al_left);
|
||||
option.setWrapMode(QTextOption::WrapAnywhere);
|
||||
p.setFont(_linkOver ? st::newGroupLink.font->underline() : st::newGroupLink.font);
|
||||
p.setPen(st::btnDefLink.color);
|
||||
p.drawText(_invitationLink, _link, option);
|
||||
if (!_goodTextLink.isEmpty() && a_goodOpacity.current() > 0) {
|
||||
p.setOpacity(a_goodOpacity.current());
|
||||
p.setPen(st::setGoodColor->p);
|
||||
p.setFont(st::setErrFont->f);
|
||||
p.drawText(QRect(st::newGroupPadding.left(), st::boxPadding.top() + _textHeight + st::newGroupLinkTop + st::newGroupLinkFont->height - st::setErrFont->ascent, width() - st::newGroupPadding.left() - st::newGroupPadding.right(), st::setErrFont->height), _goodTextLink, style::al_top);
|
||||
p.setOpacity(1);
|
||||
}
|
||||
}
|
||||
|
||||
void MaxInviteBox::resizeEvent(QResizeEvent *e) {
|
||||
_close.move(0, height() - _close.height());
|
||||
_invitationLink = QRect(st::newGroupPadding.left(), st::boxPadding.top() + _textHeight + st::newGroupLinkPadding.top() + (st::newGroupLink.height / 2) - st::newGroupLinkFont->height, width() - st::newGroupPadding.left() - st::newGroupPadding.right(), 2 * st::newGroupLinkFont->height);
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
|
||||
#include "abstractbox.h"
|
||||
|
||||
class ConfirmBox : public AbstractBox, public RPCSender {
|
||||
class ConfirmBox : public AbstractBox {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
@ -84,3 +84,41 @@ private:
|
||||
QString _url;
|
||||
|
||||
};
|
||||
|
||||
class MaxInviteBox : public AbstractBox {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
MaxInviteBox(const QString &link);
|
||||
void paintEvent(QPaintEvent *e);
|
||||
void resizeEvent(QResizeEvent *e);
|
||||
void mouseMoveEvent(QMouseEvent *e);
|
||||
void mousePressEvent(QMouseEvent *e);
|
||||
void leaveEvent(QEvent *e);
|
||||
void updateLink();
|
||||
|
||||
protected:
|
||||
|
||||
void hideAll();
|
||||
void showAll();
|
||||
|
||||
private:
|
||||
|
||||
void updateSelected(const QPoint &cursorGlobalPosition);
|
||||
bool goodAnimStep(float64 ms);
|
||||
|
||||
BottomButton _close;
|
||||
Text _text;
|
||||
int32 _textWidth, _textHeight;
|
||||
|
||||
QString _link;
|
||||
QRect _invitationLink;
|
||||
bool _linkOver;
|
||||
|
||||
QPoint _lastMousePos;
|
||||
|
||||
QString _goodTextLink;
|
||||
anim::fvalue a_goodOpacity;
|
||||
Animation a_good;
|
||||
};
|
||||
|
@ -30,7 +30,9 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
|
||||
#include "confirmbox.h"
|
||||
|
||||
ContactsInner::ContactsInner(CreatingGroupType creating) : _chat(0), _channel(0), _bot(0), _creating(creating), _addToChat(0),
|
||||
ContactsInner::ContactsInner(CreatingGroupType creating) :
|
||||
_chat(0), _channel(0), _channelFilter(MembersFilterRecent), _bot(0), _creating(creating),
|
||||
_addToChat(0), _addAdmin(0), _addAdminRequestId(0), _addAdminBox(0),
|
||||
_contacts(&App::main()->contactsList()),
|
||||
_sel(0),
|
||||
_filteredSel(-1),
|
||||
@ -42,7 +44,9 @@ _addContactLnk(this, lang(lng_add_contact_button)) {
|
||||
init();
|
||||
}
|
||||
|
||||
ContactsInner::ContactsInner(ChannelData *channel) : _chat(0), _channel(channel), _bot(0), _creating(CreatingGroupChannel), _addToChat(0),
|
||||
ContactsInner::ContactsInner(ChannelData *channel, MembersFilter channelFilter, const MembersAlreadyIn &already) :
|
||||
_chat(0), _channel(channel), _channelFilter(channelFilter), _bot(0), _creating(CreatingGroupChannel), _already(already),
|
||||
_addToChat(0), _addAdmin(0), _addAdminRequestId(0), _addAdminBox(0),
|
||||
_contacts(&App::main()->contactsList()),
|
||||
_sel(0),
|
||||
_filteredSel(-1),
|
||||
@ -54,7 +58,9 @@ _addContactLnk(this, lang(lng_add_contact_button)) {
|
||||
init();
|
||||
}
|
||||
|
||||
ContactsInner::ContactsInner(ChatData *chat) : _chat(chat), _channel(0), _bot(0), _creating(CreatingGroupNone), _addToChat(0),
|
||||
ContactsInner::ContactsInner(ChatData *chat) :
|
||||
_chat(chat), _channel(0), _channelFilter(MembersFilterRecent), _bot(0), _creating(CreatingGroupNone),
|
||||
_addToChat(0), _addAdmin(0), _addAdminRequestId(0), _addAdminBox(0),
|
||||
_contacts(&App::main()->contactsList()),
|
||||
_sel(0),
|
||||
_filteredSel(-1),
|
||||
@ -66,7 +72,9 @@ _addContactLnk(this, lang(lng_add_contact_button)) {
|
||||
init();
|
||||
}
|
||||
|
||||
ContactsInner::ContactsInner(UserData *bot) : _chat(0), _channel(0), _bot(bot), _creating(CreatingGroupNone), _addToChat(0),
|
||||
ContactsInner::ContactsInner(UserData *bot) :
|
||||
_chat(0), _channel(0), _channelFilter(MembersFilterRecent), _bot(bot), _creating(CreatingGroupNone),
|
||||
_addToChat(0), _addAdmin(0), _addAdminRequestId(0), _addAdminBox(0),
|
||||
_contacts(new DialogsIndexed(DialogsSortByAdd)),
|
||||
_sel(0),
|
||||
_filteredSel(-1),
|
||||
@ -117,6 +125,36 @@ void ContactsInner::onAddBot() {
|
||||
App::main()->showPeerHistory(_addToChat->id, ShowAtUnreadMsgId);
|
||||
}
|
||||
|
||||
void ContactsInner::onAddAdmin() {
|
||||
if (_addAdminRequestId) return;
|
||||
_addAdminRequestId = MTP::send(MTPchannels_EditAdmin(_channel->inputChannel, _addAdmin->inputUser, MTP_channelRoleEditor()), rpcDone(&ContactsInner::addAdminDone), rpcFail(&ContactsInner::addAdminFail));
|
||||
}
|
||||
|
||||
void ContactsInner::onNoAddAdminBox(QObject *obj) {
|
||||
if (obj == _addAdminBox) {
|
||||
_addAdminBox = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void ContactsInner::addAdminDone(const MTPBool &result, mtpRequestId req) {
|
||||
if (req != _addAdminRequestId) return;
|
||||
|
||||
_addAdminRequestId = 0;
|
||||
if (_addAdminBox) _addAdminBox->onClose();
|
||||
emit adminAdded();
|
||||
}
|
||||
|
||||
bool ContactsInner::addAdminFail(const RPCError &error, mtpRequestId req) {
|
||||
if (mtpIsFlood(error)) return false;
|
||||
|
||||
if (req != _addAdminRequestId) return true;
|
||||
|
||||
_addAdminRequestId = 0;
|
||||
if (_addAdminBox) _addAdminBox->onClose();
|
||||
emit adminAdded();
|
||||
return true;
|
||||
}
|
||||
|
||||
void ContactsInner::peerUpdated(PeerData *peer) {
|
||||
if (_chat && (!peer || peer == _chat)) {
|
||||
if (_chat->isForbidden || _chat->haveLeft) {
|
||||
@ -197,8 +235,10 @@ ContactsInner::ContactData *ContactsInner::contactData(DialogRow *row) {
|
||||
if (peer->isUser()) {
|
||||
if (_chat) {
|
||||
data->inchat = _chat->participants.contains(peer->asUser());
|
||||
} else if (_creating == CreatingGroupGroup || _channel) {
|
||||
} else if (_creating == CreatingGroupGroup) {
|
||||
data->inchat = (peerToUser(peer->id) == MTP::authedId());
|
||||
} else if (_channel) {
|
||||
data->inchat = (peerToUser(peer->id) == MTP::authedId()) || _already.contains(peer->asUser());
|
||||
} else {
|
||||
data->inchat = false;
|
||||
}
|
||||
@ -227,7 +267,7 @@ ContactsInner::ContactData *ContactsInner::contactData(DialogRow *row) {
|
||||
return data;
|
||||
}
|
||||
|
||||
void ContactsInner::paintDialog(QPainter &p, PeerData *peer, ContactData *data, bool sel) {
|
||||
void ContactsInner::paintDialog(Painter &p, PeerData *peer, ContactData *data, bool sel) {
|
||||
int32 left = st::profileListPadding.width();
|
||||
|
||||
UserData *user = peer->asUser();
|
||||
@ -248,9 +288,18 @@ void ContactsInner::paintDialog(QPainter &p, PeerData *peer, ContactData *data,
|
||||
p.setPen(st::profileListNameColor->p);
|
||||
}
|
||||
int32 iconw = (_chat || _creating != CreatingGroupNone) ? st::profileCheckRect.pxWidth() : st::contactsImg.pxWidth();
|
||||
data->name.drawElided(p, left + st::profileListPhotoSize + st::participantDelta, st::profileListNameTop, width() - left - st::profileListPhotoSize - st::profileListPadding.width() - st::participantDelta - st::scrollDef.width - iconw);
|
||||
int32 namew = width() - left - st::profileListPhotoSize - st::profileListPadding.width() - st::participantDelta - st::scrollDef.width - iconw;
|
||||
if (peer->isChannel() && peer->asChannel()->isVerified()) {
|
||||
namew -= st::verifiedCheck.pxWidth() + st::verifiedCheckPos.x();
|
||||
p.drawSprite(QPoint(left + st::profileListPhotoSize + st::participantDelta + qMin(data->name.maxWidth(), namew), st::profileListNameTop) + st::verifiedCheckPos, st::verifiedCheck);
|
||||
}
|
||||
data->name.drawElided(p, left + st::profileListPhotoSize + st::participantDelta, st::profileListNameTop, namew);
|
||||
|
||||
if (_chat || _creating !=CreatingGroupNone) {
|
||||
if (_channel && _channelFilter == MembersFilterAdmins) {
|
||||
if (sel) {
|
||||
p.drawPixmap(QPoint(width() - st::contactsImg.pxWidth() - st::profileCheckDeltaX, st::profileListPadding.height() + (st::profileListPhotoSize - st::contactsImg.pxHeight()) / 2 - st::profileCheckDeltaY), App::sprite(), st::contactsImg);
|
||||
}
|
||||
} else if (_chat || _creating != CreatingGroupNone) {
|
||||
if (sel || data->check) {
|
||||
p.drawPixmap(QPoint(width() - st::profileCheckRect.pxWidth() - st::profileCheckDeltaX, st::profileListPadding.height() + (st::profileListPhotoSize - st::profileCheckRect.pxHeight()) / 2 - st::profileCheckDeltaY), App::sprite(), (data->check ? st::profileCheckActiveRect : st::profileCheckRect));
|
||||
}
|
||||
@ -287,7 +336,7 @@ void ContactsInner::paintDialog(QPainter &p, PeerData *peer, ContactData *data,
|
||||
|
||||
void ContactsInner::paintEvent(QPaintEvent *e) {
|
||||
QRect r(e->rect());
|
||||
QPainter p(this);
|
||||
Painter p(this);
|
||||
|
||||
_time = unixtime();
|
||||
p.fillRect(r, st::white->b);
|
||||
@ -422,7 +471,8 @@ void ContactsInner::mousePressEvent(QMouseEvent *e) {
|
||||
}
|
||||
|
||||
void ContactsInner::chooseParticipant() {
|
||||
if (_chat || _creating != CreatingGroupNone) {
|
||||
bool addingAdmin = (_channel && _channelFilter == MembersFilterAdmins);
|
||||
if (!addingAdmin && (_chat || _creating != CreatingGroupNone)) {
|
||||
_time = unixtime();
|
||||
int32 rh = st::profileListPhotoSize + st::profileListPadding.height() * 2, from;
|
||||
if (_filter.isEmpty()) {
|
||||
@ -481,7 +531,18 @@ void ContactsInner::chooseParticipant() {
|
||||
}
|
||||
}
|
||||
if (peer) {
|
||||
if (bot() && peer->isChat()) {
|
||||
if (addingAdmin) {
|
||||
_addAdmin = peer->asUser();
|
||||
if (_addAdminRequestId) {
|
||||
MTP::cancel(_addAdminRequestId);
|
||||
_addAdminRequestId = 0;
|
||||
}
|
||||
if (_addAdminBox) _addAdminBox->deleteLater();
|
||||
_addAdminBox = new ConfirmBox(lng_channel_admin_sure(lt_user, _addAdmin->firstName));
|
||||
connect(_addAdminBox, SIGNAL(confirmed()), this, SLOT(onAddAdmin()));
|
||||
connect(_addAdminBox, SIGNAL(destroyed(QObject*)), this, SLOT(onNoAddAdminBox(QObject*)));
|
||||
App::wnd()->replaceLayer(_addAdminBox);
|
||||
} else if (bot() && peer->isChat()) {
|
||||
_addToChat = peer->asChat();
|
||||
ConfirmBox *box = new ConfirmBox(lng_bot_sure_invite(lt_group, peer->name));
|
||||
connect(box, SIGNAL(confirmed()), this, SLOT(onAddBot()));
|
||||
@ -519,7 +580,7 @@ int32 ContactsInner::selectedCount() const {
|
||||
if (_chat) {
|
||||
result += (_chat->count > 0) ? _chat->count : 1;
|
||||
} else if (_channel) {
|
||||
result += (_channel->count > 0) ? _channel->count : 1;
|
||||
result += _already.size();
|
||||
} else if (_creating == CreatingGroupGroup) {
|
||||
result += 1;
|
||||
}
|
||||
@ -785,6 +846,10 @@ ChannelData *ContactsInner::channel() const {
|
||||
return _channel;
|
||||
}
|
||||
|
||||
MembersFilter ContactsInner::channelFilter() const {
|
||||
return _channelFilter;
|
||||
}
|
||||
|
||||
UserData *ContactsInner::bot() const {
|
||||
return _bot;
|
||||
}
|
||||
@ -1017,6 +1082,15 @@ _creationRequestId(0) {
|
||||
init();
|
||||
}
|
||||
|
||||
ContactsBox::ContactsBox(ChannelData *channel, MembersFilter filter, const MembersAlreadyIn &already) : ItemListBox(st::boxNoTopScroll), _inner(channel, filter, already),
|
||||
_addContact(this, lang(lng_add_contact_button), st::contactsAdd),
|
||||
_filter(this, st::contactsFilter, lang(lng_participant_filter)),
|
||||
_next(this, lang(lng_participant_invite), st::btnSelectDone),
|
||||
_cancel(this, lang(filter == MembersFilterAdmins ? lng_contacts_done : lng_cancel), (filter == MembersFilterAdmins ? st::contactsClose : st::btnSelectCancel)),
|
||||
_creationRequestId(0) {
|
||||
init();
|
||||
}
|
||||
|
||||
ContactsBox::ContactsBox(ChatData *chat) : ItemListBox(st::boxNoTopScroll), _inner(chat),
|
||||
_addContact(this, lang(lng_add_contact_button), st::contactsAdd),
|
||||
_filter(this, st::contactsFilter, lang(lng_participant_filter)),
|
||||
@ -1060,6 +1134,7 @@ void ContactsBox::init() {
|
||||
connect(&_inner, SIGNAL(mustScrollTo(int, int)), &_scroll, SLOT(scrollToY(int, int)));
|
||||
connect(&_inner, SIGNAL(selectAllQuery()), &_filter, SLOT(selectAll()));
|
||||
connect(&_inner, SIGNAL(searchByUsername()), this, SLOT(onNeedSearchByUsername()));
|
||||
connect(&_inner, SIGNAL(adminAdded()), this, SIGNAL(adminAdded()));
|
||||
|
||||
_searchTimer.setSingleShot(true);
|
||||
connect(&_searchTimer, SIGNAL(timeout()), this, SLOT(onSearchByUsername()));
|
||||
@ -1146,7 +1221,10 @@ void ContactsBox::hideAll() {
|
||||
void ContactsBox::showAll() {
|
||||
ItemListBox::showAll();
|
||||
_filter.show();
|
||||
if (_inner.chat()) {
|
||||
if (_inner.channel() && _inner.channelFilter() == MembersFilterAdmins) {
|
||||
_next.hide();
|
||||
_addContact.hide();
|
||||
} else if (_inner.chat()) {
|
||||
_next.show();
|
||||
_addContact.hide();
|
||||
} else if (_inner.creating() != CreatingGroupNone) {
|
||||
@ -1195,15 +1273,18 @@ void ContactsBox::paintEvent(QPaintEvent *e) {
|
||||
Painter p(this);
|
||||
if (paint(p)) return;
|
||||
|
||||
bool addingAdmin = _inner.channel() && _inner.channelFilter() == MembersFilterAdmins;
|
||||
if (_inner.chat() || _inner.creating() != CreatingGroupNone) {
|
||||
QString title(lang(lng_profile_add_participant));
|
||||
QString title(lang(addingAdmin ? lng_channel_add_admin : lng_profile_add_participant));
|
||||
paintTitle(p, title, true);
|
||||
|
||||
p.setPen(st::newGroupLimitFg);
|
||||
p.drawTextLeft(st::boxTitlePos.x() + st::boxTitleFont->m.width(title) + st::addContactDelta, st::boxTitlePos.y(), width(), QString("%1 / %2").arg(_inner.selectedCount()).arg(cMaxGroupCount()));
|
||||
if (!addingAdmin) {
|
||||
p.setPen(st::newGroupLimitFg);
|
||||
p.drawTextLeft(st::boxTitlePos.x() + st::boxTitleFont->m.width(title) + st::addContactDelta, st::boxTitlePos.y(), width(), QString("%1 / %2").arg(_inner.selectedCount()).arg(cMaxGroupCount()));
|
||||
|
||||
// paint button sep
|
||||
p.fillRect(st::btnSelectCancel.width, size().height() - st::btnSelectCancel.height, st::lineWidth, st::btnSelectCancel.height, st::btnSelectSep->b);
|
||||
// paint button sep
|
||||
p.fillRect(st::btnSelectCancel.width, size().height() - st::btnSelectCancel.height, st::lineWidth, st::btnSelectCancel.height, st::btnSelectSep->b);
|
||||
}
|
||||
} else if (_inner.bot()) {
|
||||
paintTitle(p, lang(lng_bot_choose_group), true);
|
||||
} else {
|
||||
@ -1221,7 +1302,7 @@ void ContactsBox::resizeEvent(QResizeEvent *e) {
|
||||
}
|
||||
|
||||
void ContactsBox::closePressed() {
|
||||
if (_inner.channel()) {
|
||||
if (_inner.channel() && !_inner.hasAlreadyMembersInChannel()) {
|
||||
App::main()->showPeerHistory(_inner.channel()->id, ShowAtTheEndMsgId);
|
||||
}
|
||||
}
|
||||
@ -1335,11 +1416,551 @@ bool ContactsBox::creationFail(const RPCError &error) {
|
||||
return false;
|
||||
}
|
||||
|
||||
MembersInner::MembersInner(ChannelData *channel, MembersFilter filter) : _channel(channel), _filter(filter),
|
||||
_time(0),
|
||||
_kickText(lang(lng_profile_kick)),
|
||||
_kickWidth(st::normalFont->m.width(_kickText)),
|
||||
_sel(-1),
|
||||
_kickSel(-1),
|
||||
_kickDown(-1),
|
||||
_mouseSel(false),
|
||||
_kickConfirm(0),
|
||||
_kickRequestId(0),
|
||||
_kickBox(0),
|
||||
_loading(true),
|
||||
_loadingRequestId(0) {
|
||||
connect(App::main(), SIGNAL(peerNameChanged(PeerData*,const PeerData::Names&,const PeerData::NameFirstChars&)), this, SLOT(onPeerNameChanged(PeerData*,const PeerData::Names&,const PeerData::NameFirstChars&)));
|
||||
connect(App::main(), SIGNAL(peerPhotoChanged(PeerData*)), this, SLOT(peerUpdated(PeerData*)));
|
||||
|
||||
refresh();
|
||||
|
||||
load();
|
||||
}
|
||||
|
||||
void MembersInner::load() {
|
||||
if (!_loadingRequestId) {
|
||||
_loadingRequestId = MTP::send(MTPchannels_GetParticipants(_channel->inputChannel, (_filter == MembersFilterRecent) ? MTP_channelParticipantsRecent() : MTP_channelParticipantsAdmins(), MTP_int(0), MTP_int(cMaxGroupCount())), rpcDone(&MembersInner::membersReceived), rpcFail(&MembersInner::membersFailed));
|
||||
}
|
||||
}
|
||||
|
||||
void MembersInner::paintEvent(QPaintEvent *e) {
|
||||
QRect r(e->rect());
|
||||
Painter p(this);
|
||||
|
||||
_time = unixtime();
|
||||
p.fillRect(r, st::white->b);
|
||||
|
||||
int32 yFrom = r.top(), yTo = r.bottom();
|
||||
int32 rh = st::profileListPhotoSize + st::profileListPadding.height() * 2;
|
||||
|
||||
p.translate(0, st::membersPadding.top());
|
||||
if (_rows.isEmpty()) {
|
||||
p.setFont(st::noContactsFont->f);
|
||||
p.setPen(st::noContactsColor->p);
|
||||
p.drawText(QRect(0, 0, width(), st::noContactsHeight), lang(lng_contacts_loading), style::al_center);
|
||||
} else {
|
||||
int32 from = (yFrom >= 0) ? (yFrom / rh) : 0;
|
||||
if (from < _rows.size()) {
|
||||
int32 to = (yTo / rh) + 1;
|
||||
if (to > _rows.size()) to = _rows.size();
|
||||
|
||||
p.translate(0, from * rh);
|
||||
for (; from < to; ++from) {
|
||||
bool sel = (from == _sel);
|
||||
bool kickSel = (from == _kickSel && (_kickDown < 0 || from == _kickDown));
|
||||
bool kickDown = kickSel && (from == _kickDown);
|
||||
paintDialog(p, _rows[from], data(from), sel, kickSel, kickDown);
|
||||
p.translate(0, rh);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MembersInner::enterEvent(QEvent *e) {
|
||||
setMouseTracking(true);
|
||||
}
|
||||
|
||||
void MembersInner::leaveEvent(QEvent *e) {
|
||||
setMouseTracking(false);
|
||||
if (_sel >= 0) {
|
||||
_sel = -1;
|
||||
parentWidget()->update();
|
||||
}
|
||||
}
|
||||
|
||||
void MembersInner::mouseMoveEvent(QMouseEvent *e) {
|
||||
_mouseSel = true;
|
||||
_lastMousePos = e->globalPos();
|
||||
updateSel();
|
||||
}
|
||||
|
||||
void MembersInner::mousePressEvent(QMouseEvent *e) {
|
||||
_mouseSel = true;
|
||||
_lastMousePos = e->globalPos();
|
||||
updateSel();
|
||||
if (e->button() == Qt::LeftButton && _kickSel < 0) {
|
||||
chooseParticipant();
|
||||
}
|
||||
_kickDown = _kickSel;
|
||||
update();
|
||||
}
|
||||
|
||||
void MembersInner::mouseReleaseEvent(QMouseEvent *e) {
|
||||
_mouseSel = true;
|
||||
_lastMousePos = e->globalPos();
|
||||
updateSel();
|
||||
if (_kickDown >= 0 && _kickDown == _kickSel && !_kickRequestId) {
|
||||
_kickConfirm = _rows.at(_kickSel);
|
||||
if (_kickBox) _kickBox->deleteLater();
|
||||
_kickBox = new ConfirmBox((_filter == MembersFilterRecent ? lng_profile_sure_kick_channel : lng_profile_sure_kick_admin)(lt_user, _kickConfirm->firstName));
|
||||
connect(_kickBox, SIGNAL(confirmed()), this, SLOT(onKickConfirm()));
|
||||
connect(_kickBox, SIGNAL(destroyed(QObject*)), this, SLOT(onKickBoxDestroyed(QObject*)));
|
||||
App::wnd()->replaceLayer(_kickBox);
|
||||
}
|
||||
_kickDown = -1;
|
||||
}
|
||||
|
||||
void MembersInner::onKickBoxDestroyed(QObject *obj) {
|
||||
if (_kickBox == obj) {
|
||||
_kickBox = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void MembersInner::onKickConfirm() {
|
||||
if (_filter == MembersFilterRecent) {
|
||||
_kickRequestId = MTP::send(MTPchannels_KickFromChannel(_channel->inputChannel, _kickConfirm->inputUser, MTP_bool(true)), rpcDone(&MembersInner::kickDone), rpcFail(&MembersInner::kickFail));
|
||||
} else {
|
||||
_kickRequestId = MTP::send(MTPchannels_EditAdmin(_channel->inputChannel, _kickConfirm->inputUser, MTP_channelRoleEmpty()), rpcDone(&MembersInner::kickAdminDone), rpcFail(&MembersInner::kickFail));
|
||||
}
|
||||
}
|
||||
|
||||
void MembersInner::paintDialog(Painter &p, PeerData *peer, MemberData *data, bool sel, bool kickSel, bool kickDown) {
|
||||
int32 left = st::profileListPadding.width();
|
||||
|
||||
UserData *user = peer->asUser();
|
||||
if (sel) {
|
||||
p.fillRect(0, 0, width(), 2 * st::profileListPadding.height() + st::profileListPhotoSize, st::profileHoverBG->b);
|
||||
}
|
||||
|
||||
p.drawPixmap(left, st::profileListPadding.height(), peer->photo->pix(st::profileListPhotoSize));
|
||||
|
||||
p.setPen(st::profileListNameColor->p);
|
||||
|
||||
data->name.drawElided(p, left + st::profileListPhotoSize + st::participantDelta, st::profileListNameTop, width() - left - st::profileListPhotoSize - st::profileListPadding.width() - st::participantDelta - st::scrollDef.width - (data->canKick ? _kickWidth : 0));
|
||||
|
||||
if (data->canKick) {
|
||||
p.setFont((kickSel ? st::linkOverFont : st::linkFont)->f);
|
||||
if (kickDown) {
|
||||
p.setPen(st::btnDefLink.downColor->p);
|
||||
} else {
|
||||
p.setPen(st::btnDefLink.color->p);
|
||||
}
|
||||
p.drawText(width() - _kickWidth - st::profileCheckDeltaX, st::profileListPadding.height() + (st::profileListPhotoSize - st::normalFont->height) / 2 + st::normalFont->ascent, _kickText);
|
||||
}
|
||||
|
||||
p.setFont(st::normalFont);
|
||||
p.setPen(st::profileOfflineColor->p);
|
||||
p.drawText(left + st::profileListPhotoSize + st::profileListPadding.width(), st::profileListPadding.height() + st::profileListPhotoSize - st::profileListStatusBottom, data->online);
|
||||
}
|
||||
|
||||
void MembersInner::selectSkip(int32 dir) {
|
||||
_time = unixtime();
|
||||
_mouseSel = false;
|
||||
int32 rh = st::profileListPhotoSize + st::profileListPadding.height() * 2, origDir = dir;
|
||||
|
||||
int cur = (_sel >= 0) ? _sel : -1;
|
||||
cur += dir;
|
||||
if (cur <= 0) {
|
||||
_sel = _rows.isEmpty() ? -1 : 0;
|
||||
} else if (cur >= _rows.size()) {
|
||||
_sel = -1;
|
||||
} else {
|
||||
_sel = cur;
|
||||
}
|
||||
if (dir > 0) {
|
||||
if (_sel < 0 || _sel >= _rows.size()) {
|
||||
_sel = -1;
|
||||
}
|
||||
} else {
|
||||
if (!_rows.isEmpty()) {
|
||||
if (_sel < 0) _sel = _rows.size() - 1;
|
||||
}
|
||||
}
|
||||
if (_sel >= 0) {
|
||||
emit mustScrollTo(_sel * rh, (_sel + 1) * rh);
|
||||
}
|
||||
|
||||
parentWidget()->update();
|
||||
}
|
||||
|
||||
void MembersInner::selectSkipPage(int32 h, int32 dir) {
|
||||
int32 rh = st::profileListPhotoSize + st::profileListPadding.height() * 2;
|
||||
int32 points = h / rh;
|
||||
if (!points) return;
|
||||
selectSkip(points * dir);
|
||||
}
|
||||
|
||||
void MembersInner::loadProfilePhotos(int32 yFrom) {
|
||||
int32 yTo = yFrom + (parentWidget() ? parentWidget()->height() : App::wnd()->height()) * 5;
|
||||
MTP::clearLoaderPriorities();
|
||||
|
||||
if (yTo < 0) return;
|
||||
if (yFrom < 0) yFrom = 0;
|
||||
|
||||
int32 rh = st::profileListPhotoSize + st::profileListPadding.height() * 2;
|
||||
if (!_rows.isEmpty()) {
|
||||
int32 from = yFrom / rh;
|
||||
if (from < 0) from = 0;
|
||||
if (from < _rows.size()) {
|
||||
int32 to = (yTo / rh) + 1;
|
||||
if (to > _rows.size()) to = _rows.size();
|
||||
|
||||
for (; from < to; ++from) {
|
||||
_rows[from]->photo->load();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MembersInner::chooseParticipant() {
|
||||
int32 rh = st::profileListPhotoSize + st::profileListPadding.height() * 2, from;
|
||||
if (_sel < 0 || _sel >= _rows.size()) return;
|
||||
if (PeerData *peer = _rows[_sel]) {
|
||||
App::wnd()->hideLayer();
|
||||
App::main()->showPeerProfile(peer, ShowAtUnreadMsgId);
|
||||
}
|
||||
}
|
||||
|
||||
void MembersInner::refresh() {
|
||||
int32 rh = st::profileListPhotoSize + st::profileListPadding.height() * 2;
|
||||
if (_rows.isEmpty()) {
|
||||
resize(width(), st::membersPadding.top() + st::noContactsHeight + st::membersPadding.bottom());
|
||||
} else {
|
||||
resize(width(), st::membersPadding.top() + _rows.size() * rh + st::membersPadding.bottom());
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
ChannelData *MembersInner::channel() const {
|
||||
return _channel;
|
||||
}
|
||||
|
||||
MembersFilter MembersInner::filter() const {
|
||||
return _filter;
|
||||
}
|
||||
|
||||
QMap<UserData*, bool> MembersInner::already() const {
|
||||
MembersAlreadyIn result;
|
||||
for (int32 i = 0, l = _rows.size(); i < l; ++i) {
|
||||
if (_rows.at(i)->isUser()) {
|
||||
result.insert(_rows.at(i)->asUser(), true);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void MembersInner::clearSel() {
|
||||
_sel = _kickSel = _kickDown = -1;
|
||||
_lastMousePos = QCursor::pos();
|
||||
updateSel();
|
||||
}
|
||||
|
||||
MembersInner::MemberData *MembersInner::data(int32 index) {
|
||||
if (MemberData *result = _datas.at(index)) {
|
||||
return result;
|
||||
}
|
||||
MemberData *result = _datas[index] = new MemberData();
|
||||
result->name.setText(st::profileListNameFont, _rows[index]->name, _textNameOptions);
|
||||
result->online = lng_mediaview_date_time(lt_date, _dates[index].date().toString(qsl("dd.MM.yy")), lt_time, _dates[index].time().toString(cTimeFormat()));
|
||||
if (_filter == MembersFilterRecent) {
|
||||
result->canKick = (_channel->amCreator() || _channel->amEditor() || _channel->amModerator()) ? (_roles[index] == MemberRoleNone) : false;
|
||||
} else if (_filter == MembersFilterAdmins) {
|
||||
result->canKick = _channel->amCreator() ? (_roles[index] == MemberRoleEditor || _roles[index] == MemberRoleModerator) : false;
|
||||
} else {
|
||||
result->canKick = false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void MembersInner::clear() {
|
||||
for (int32 i = 0, l = _datas.size(); i < l; ++i) {
|
||||
delete _datas.at(i);
|
||||
}
|
||||
_datas.clear();
|
||||
_rows.clear();
|
||||
_dates.clear();
|
||||
_roles.clear();
|
||||
if (_kickBox) _kickBox->deleteLater();
|
||||
clearSel();
|
||||
}
|
||||
|
||||
MembersInner::~MembersInner() {
|
||||
clear();
|
||||
}
|
||||
|
||||
void MembersInner::updateSel() {
|
||||
QPoint p(mapFromGlobal(_lastMousePos));
|
||||
p.setY(p.y() - st::membersPadding.top());
|
||||
bool in = parentWidget()->rect().contains(parentWidget()->mapFromGlobal(_lastMousePos));
|
||||
int32 rh = st::profileListPhotoSize + st::profileListPadding.height() * 2;
|
||||
int32 newSel = (in && p.y() >= 0 && p.y() < _rows.size() * rh) ? (p.y() / rh) : -1;
|
||||
int32 newKickSel = newSel;
|
||||
if (newSel >= 0 && (!data(newSel)->canKick || !QRect(width() - _kickWidth - st::profileCheckDeltaX, newSel * rh + st::profileListPadding.height() + (st::profileListPhotoSize - st::normalFont->height) / 2, _kickWidth, st::normalFont->height).contains(p))) {
|
||||
newKickSel = -1;
|
||||
}
|
||||
if (newSel != _sel || newKickSel != _kickSel) {
|
||||
_sel = newSel;
|
||||
_kickSel = newKickSel;
|
||||
parentWidget()->update();
|
||||
setCursor(_kickSel >= 0 ? style::cur_pointer : style::cur_default);
|
||||
}
|
||||
}
|
||||
|
||||
void MembersInner::peerUpdated(PeerData *peer) {
|
||||
parentWidget()->update();
|
||||
}
|
||||
|
||||
void MembersInner::onPeerNameChanged(PeerData *peer, const PeerData::Names &oldNames, const PeerData::NameFirstChars &oldChars) {
|
||||
for (int32 i = 0, l = _rows.size(); i < l; ++i) {
|
||||
if (_rows.at(i) == peer) {
|
||||
if (_datas.at(i)) {
|
||||
_datas.at(i)->name.setText(st::profileListNameFont, peer->name, _textNameOptions);
|
||||
parentWidget()->update();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MembersInner::membersReceived(const MTPchannels_ChannelParticipants &result, mtpRequestId req) {
|
||||
clear();
|
||||
_loadingRequestId = 0;
|
||||
|
||||
if (result.type() == mtpc_channels_channelParticipants) {
|
||||
const MTPDchannels_channelParticipants &d(result.c_channels_channelParticipants());
|
||||
const QVector<MTPChannelParticipant> &v(d.vparticipants.c_vector().v);
|
||||
_rows.reserve(v.size());
|
||||
_datas.reserve(v.size());
|
||||
_dates.reserve(v.size());
|
||||
_roles.reserve(v.size());
|
||||
if (_filter == MembersFilterRecent && _channel->count != d.vcount.v) {
|
||||
_channel->count = d.vcount.v;
|
||||
if (App::main()) emit App::main()->peerUpdated(_channel);
|
||||
} else if (_filter == MembersFilterAdmins && _channel->adminsCount != d.vcount.v) {
|
||||
_channel->adminsCount = d.vcount.v;
|
||||
if (App::main()) emit App::main()->peerUpdated(_channel);
|
||||
}
|
||||
App::feedUsers(d.vusers);
|
||||
for (QVector<MTPChannelParticipant>::const_iterator i = v.cbegin(), e = v.cend(); i != e; ++i) {
|
||||
int32 userId = 0, addedTime = 0;
|
||||
MemberRole role = MemberRoleNone;
|
||||
switch (i->type()) {
|
||||
case mtpc_channelParticipant:
|
||||
userId = i->c_channelParticipant().vuser_id.v;
|
||||
addedTime = i->c_channelParticipant().vdate.v;
|
||||
break;
|
||||
case mtpc_channelParticipantSelf:
|
||||
role = MemberRoleSelf;
|
||||
userId = i->c_channelParticipantSelf().vuser_id.v;
|
||||
addedTime = i->c_channelParticipantSelf().vdate.v;
|
||||
break;
|
||||
case mtpc_channelParticipantModerator:
|
||||
role = MemberRoleModerator;
|
||||
userId = i->c_channelParticipantModerator().vuser_id.v;
|
||||
addedTime = i->c_channelParticipantModerator().vdate.v;
|
||||
break;
|
||||
case mtpc_channelParticipantEditor:
|
||||
role = MemberRoleEditor;
|
||||
userId = i->c_channelParticipantEditor().vuser_id.v;
|
||||
addedTime = i->c_channelParticipantEditor().vdate.v;
|
||||
break;
|
||||
case mtpc_channelParticipantKicked:
|
||||
userId = i->c_channelParticipantKicked().vuser_id.v;
|
||||
addedTime = i->c_channelParticipantKicked().vdate.v;
|
||||
role = MemberRoleKicked;
|
||||
break;
|
||||
case mtpc_channelParticipantCreator:
|
||||
userId = i->c_channelParticipantCreator().vuser_id.v;
|
||||
addedTime = _channel->date;
|
||||
role = MemberRoleCreator;
|
||||
break;
|
||||
}
|
||||
if (UserData *user = App::userLoaded(userId)) {
|
||||
_rows.push_back(user);
|
||||
_dates.push_back(date(addedTime));
|
||||
_roles.push_back(role);
|
||||
_datas.push_back(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (_rows.isEmpty()) {
|
||||
_rows.push_back(App::self());
|
||||
_dates.push_back(date(MTP_int(_channel->date)));
|
||||
_roles.push_back(MemberRoleSelf);
|
||||
_datas.push_back(0);
|
||||
}
|
||||
|
||||
clearSel();
|
||||
_loading = false;
|
||||
refresh();
|
||||
|
||||
emit loaded();
|
||||
}
|
||||
|
||||
bool MembersInner::membersFailed(const RPCError &error, mtpRequestId req) {
|
||||
if (mtpIsFlood(error)) return false;
|
||||
App::wnd()->hideLayer();
|
||||
return true;
|
||||
}
|
||||
|
||||
void MembersInner::kickDone(const MTPUpdates &result, mtpRequestId req) {
|
||||
App::main()->sentUpdatesReceived(result);
|
||||
|
||||
if (_kickRequestId != req) return;
|
||||
removeKicked();
|
||||
if (_kickBox) _kickBox->onClose();
|
||||
}
|
||||
|
||||
void MembersInner::kickAdminDone(const MTPBool &result, mtpRequestId req) {
|
||||
if (_kickRequestId != req) return;
|
||||
removeKicked();
|
||||
if (_kickBox) _kickBox->onClose();
|
||||
}
|
||||
|
||||
bool MembersInner::kickFail(const RPCError &error, mtpRequestId req) {
|
||||
if (mtpIsFlood(error)) return false;
|
||||
|
||||
if (_kickBox) _kickBox->onClose();
|
||||
load();
|
||||
return true;
|
||||
}
|
||||
|
||||
void MembersInner::removeKicked() {
|
||||
_kickRequestId = 0;
|
||||
int32 index = _rows.indexOf(_kickConfirm);
|
||||
if (index >= 0) {
|
||||
_rows.removeAt(index);
|
||||
delete _datas.at(index);
|
||||
_datas.removeAt(index);
|
||||
_dates.removeAt(index);
|
||||
_roles.removeAt(index);
|
||||
clearSel();
|
||||
if (_filter == MembersFilterRecent && _channel->count > 1) {
|
||||
--_channel->count;
|
||||
if (App::main()) emit App::main()->peerUpdated(_channel);
|
||||
} else if (_filter == MembersFilterAdmins && _channel->adminsCount > 1) {
|
||||
--_channel->adminsCount;
|
||||
if (App::main()) emit App::main()->peerUpdated(_channel);
|
||||
}
|
||||
}
|
||||
_kickConfirm = 0;
|
||||
}
|
||||
|
||||
MembersBox::MembersBox(ChannelData *channel, MembersFilter filter) : ItemListBox(st::boxScroll), _inner(channel, filter),
|
||||
_add(this, lang(filter == MembersFilterRecent ? lng_participant_invite : lng_channel_add_admins), st::contactsAdd),
|
||||
_done(this, lang(lng_contacts_done), st::contactsClose),
|
||||
_addBox(0) {
|
||||
ItemListBox::init(&_inner, _done.height());
|
||||
|
||||
connect(&_add, SIGNAL(clicked()), this, SLOT(onAdd()));
|
||||
|
||||
connect(&_done, SIGNAL(clicked()), this, SLOT(onClose()));
|
||||
connect(&_scroll, SIGNAL(scrolled()), &_inner, SLOT(updateSel()));
|
||||
connect(&_scroll, SIGNAL(scrolled()), this, SLOT(onScroll()));
|
||||
connect(&_inner, SIGNAL(mustScrollTo(int, int)), &_scroll, SLOT(scrollToY(int, int)));
|
||||
connect(&_inner, SIGNAL(loaded()), this, SLOT(onLoaded()));
|
||||
|
||||
prepare();
|
||||
}
|
||||
|
||||
void MembersBox::keyPressEvent(QKeyEvent *e) {
|
||||
if (e->key() == Qt::Key_Down) {
|
||||
_inner.selectSkip(1);
|
||||
} else if (e->key() == Qt::Key_Up) {
|
||||
_inner.selectSkip(-1);
|
||||
} else if (e->key() == Qt::Key_PageDown) {
|
||||
_inner.selectSkipPage(_scroll.height(), 1);
|
||||
} else if (e->key() == Qt::Key_PageUp) {
|
||||
_inner.selectSkipPage(_scroll.height(), -1);
|
||||
} else {
|
||||
ItemListBox::keyPressEvent(e);
|
||||
}
|
||||
}
|
||||
|
||||
void MembersBox::paintEvent(QPaintEvent *e) {
|
||||
Painter p(this);
|
||||
if (paint(p)) return;
|
||||
|
||||
QString title(lang(_inner.filter() == MembersFilterRecent ? lng_channel_members : lng_channel_admins));
|
||||
paintTitle(p, title, false);
|
||||
}
|
||||
|
||||
void MembersBox::resizeEvent(QResizeEvent *e) {
|
||||
ItemListBox::resizeEvent(e);
|
||||
_inner.resize(width(), _inner.height());
|
||||
_done.move(0, height() - _done.height());
|
||||
_add.move(width() - _add.width(), 0);
|
||||
}
|
||||
|
||||
void MembersBox::onLoaded() {
|
||||
if (!_done.isHidden() && _inner.channel()->amCreator() && (_inner.channel()->count < cMaxGroupCount() || !_inner.channel()->isPublic())) {
|
||||
_add.show();
|
||||
}
|
||||
}
|
||||
|
||||
void MembersBox::onScroll() {
|
||||
_inner.loadProfilePhotos(_scroll.scrollTop());
|
||||
}
|
||||
|
||||
void MembersBox::onAdd() {
|
||||
if (_inner.filter() == MembersFilterRecent && _inner.channel()->count >= cMaxGroupCount()) {
|
||||
App::wnd()->replaceLayer(new MaxInviteBox(_inner.channel()->invitationUrl));
|
||||
return;
|
||||
}
|
||||
ContactsBox *box = new ContactsBox(_inner.channel(), _inner.filter(), _inner.already());
|
||||
if (_inner.filter() == MembersFilterRecent) {
|
||||
App::wnd()->hideLayer(true);
|
||||
App::wnd()->showLayer(box, true);
|
||||
} else {
|
||||
_addBox = box;
|
||||
connect(_addBox, SIGNAL(adminAdded()), this, SLOT(onAdminAdded()));
|
||||
App::wnd()->replaceLayer(_addBox);
|
||||
}
|
||||
}
|
||||
|
||||
void MembersBox::onAdminAdded() {
|
||||
if (!_addBox) return;
|
||||
_addBox->onClose();
|
||||
_addBox = 0;
|
||||
_inner.load();
|
||||
}
|
||||
|
||||
void MembersBox::hideAll() {
|
||||
ItemListBox::hideAll();
|
||||
_add.hide();
|
||||
_done.hide();
|
||||
}
|
||||
|
||||
void MembersBox::showAll() {
|
||||
ItemListBox::showAll();
|
||||
if (_inner.channel()->amCreator() && _inner.isLoaded() && (_inner.channel()->count < cMaxGroupCount() || !_inner.channel()->isPublic())) {
|
||||
_add.show();
|
||||
} else {
|
||||
_add.hide();
|
||||
}
|
||||
_done.show();
|
||||
}
|
||||
|
||||
void MembersBox::showDone() {
|
||||
setFocus();
|
||||
}
|
||||
|
||||
NewGroupBox::NewGroupBox() : AbstractBox(),
|
||||
_group(this, qsl("group_type"), 0, lang(lng_create_group_title), true),
|
||||
_channel(this, qsl("group_type"), 1, lang(lng_create_channel_title)),
|
||||
_aboutGroupWidth(width() - st::newGroupPadding.left() - st::newGroupPadding.right() - st::rbDefFlat.textLeft),
|
||||
_aboutGroup(st::normalFont, lang(lng_create_group_about), _defaultOptions, _aboutGroupWidth),
|
||||
_aboutGroup(st::normalFont, lng_create_group_about(lt_count, QString::number(cMaxGroupCount())), _defaultOptions, _aboutGroupWidth),
|
||||
_aboutChannel(st::normalFont, lang(lng_create_channel_about), _defaultOptions, _aboutGroupWidth),
|
||||
_next(this, lang(lng_create_group_next), st::btnSelectDone),
|
||||
_cancel(this, lang(lng_cancel), st::btnSelectCancel) {
|
||||
@ -1900,6 +2521,10 @@ void SetupChannelBox::mousePressEvent(QMouseEvent *e) {
|
||||
}
|
||||
}
|
||||
|
||||
void SetupChannelBox::leaveEvent(QEvent *e) {
|
||||
updateSelected(QCursor::pos());
|
||||
}
|
||||
|
||||
void SetupChannelBox::updateSelected(const QPoint &cursorGlobalPosition) {
|
||||
QPoint p(mapFromGlobal(cursorGlobalPosition));
|
||||
|
||||
|
@ -25,7 +25,14 @@ enum CreatingGroupType {
|
||||
CreatingGroupChannel,
|
||||
};
|
||||
|
||||
class ContactsInner : public QWidget, public RPCSender {
|
||||
enum MembersFilter {
|
||||
MembersFilterRecent,
|
||||
MembersFilterAdmins,
|
||||
};
|
||||
typedef QMap<UserData*, bool> MembersAlreadyIn;
|
||||
|
||||
class ConfirmBox;
|
||||
class ContactsInner : public TWidget, public RPCSender {
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
@ -35,7 +42,7 @@ private:
|
||||
public:
|
||||
|
||||
ContactsInner(CreatingGroupType creating = CreatingGroupNone);
|
||||
ContactsInner(ChannelData *channel);
|
||||
ContactsInner(ChannelData *channel, MembersFilter channelFilter = MembersFilterRecent, const MembersAlreadyIn &already = MembersAlreadyIn());
|
||||
ContactsInner(ChatData *chat);
|
||||
ContactsInner(UserData *bot);
|
||||
void init();
|
||||
@ -47,7 +54,7 @@ public:
|
||||
void mousePressEvent(QMouseEvent *e);
|
||||
void resizeEvent(QResizeEvent *e);
|
||||
|
||||
void paintDialog(QPainter &p, PeerData *peer, ContactData *data, bool sel);
|
||||
void paintDialog(Painter &p, PeerData *peer, ContactData *data, bool sel);
|
||||
void updateFilter(QString filter = QString());
|
||||
|
||||
void selectSkip(int32 dir);
|
||||
@ -68,10 +75,14 @@ public:
|
||||
|
||||
ChatData *chat() const;
|
||||
ChannelData *channel() const;
|
||||
MembersFilter channelFilter() const;
|
||||
UserData *bot() const;
|
||||
CreatingGroupType creating() const;
|
||||
|
||||
int32 selectedCount() const;
|
||||
bool hasAlreadyMembersInChannel() const {
|
||||
return !_already.isEmpty();
|
||||
}
|
||||
|
||||
~ContactsInner();
|
||||
|
||||
@ -81,6 +92,7 @@ signals:
|
||||
void selectAllQuery();
|
||||
void searchByUsername();
|
||||
void chosenChanged();
|
||||
void adminAdded();
|
||||
|
||||
public slots:
|
||||
|
||||
@ -91,15 +103,25 @@ public slots:
|
||||
void onPeerNameChanged(PeerData *peer, const PeerData::Names &oldNames, const PeerData::NameFirstChars &oldChars);
|
||||
|
||||
void onAddBot();
|
||||
void onAddAdmin();
|
||||
void onNoAddAdminBox(QObject *obj);
|
||||
|
||||
private:
|
||||
|
||||
void addAdminDone(const MTPBool &result, mtpRequestId req);
|
||||
bool addAdminFail(const RPCError &error, mtpRequestId req);
|
||||
|
||||
ChatData *_chat;
|
||||
ChannelData *_channel;
|
||||
MembersFilter _channelFilter;
|
||||
UserData *_bot;
|
||||
CreatingGroupType _creating;
|
||||
MembersAlreadyIn _already;
|
||||
|
||||
ChatData *_addToChat;
|
||||
UserData *_addAdmin;
|
||||
mtpRequestId _addAdminRequestId;
|
||||
ConfirmBox *_addAdminBox;
|
||||
|
||||
int32 _time;
|
||||
|
||||
@ -148,6 +170,7 @@ public:
|
||||
ContactsBox();
|
||||
ContactsBox(const QString &name, const QImage &photo); // group creation
|
||||
ContactsBox(ChannelData *channel); // channel setup
|
||||
ContactsBox(ChannelData *channel, MembersFilter filter, const MembersAlreadyIn &already);
|
||||
ContactsBox(ChatData *chat);
|
||||
ContactsBox(UserData *bot);
|
||||
void keyPressEvent(QKeyEvent *e);
|
||||
@ -160,6 +183,10 @@ public:
|
||||
_filter.setFocus();
|
||||
}
|
||||
|
||||
signals:
|
||||
|
||||
void adminAdded();
|
||||
|
||||
public slots:
|
||||
|
||||
void onFilterUpdate();
|
||||
@ -187,6 +214,7 @@ private:
|
||||
FlatInput _filter;
|
||||
|
||||
FlatButton _next, _cancel;
|
||||
MembersFilter _membersFilter;
|
||||
|
||||
void peopleReceived(const MTPcontacts_Found &result, mtpRequestId req);
|
||||
bool peopleFailed(const RPCError &error, mtpRequestId req);
|
||||
@ -211,6 +239,155 @@ private:
|
||||
bool creationFail(const RPCError &e);
|
||||
};
|
||||
|
||||
class MembersInner : public TWidget, public RPCSender {
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
|
||||
struct MemberData;
|
||||
|
||||
public:
|
||||
|
||||
MembersInner(ChannelData *channel, MembersFilter filter);
|
||||
|
||||
void paintEvent(QPaintEvent *e);
|
||||
void enterEvent(QEvent *e);
|
||||
void leaveEvent(QEvent *e);
|
||||
void mouseMoveEvent(QMouseEvent *e);
|
||||
void mousePressEvent(QMouseEvent *e);
|
||||
void mouseReleaseEvent(QMouseEvent *e);
|
||||
|
||||
void paintDialog(Painter &p, PeerData *peer, MemberData *data, bool sel, bool kickSel, bool kickDown);
|
||||
|
||||
void selectSkip(int32 dir);
|
||||
void selectSkipPage(int32 h, int32 dir);
|
||||
|
||||
void loadProfilePhotos(int32 yFrom);
|
||||
void chooseParticipant();
|
||||
|
||||
void refresh();
|
||||
|
||||
ChannelData *channel() const;
|
||||
MembersFilter filter() const;
|
||||
|
||||
void load();
|
||||
bool isLoaded() const {
|
||||
return !_loading;
|
||||
}
|
||||
|
||||
QMap<UserData*, bool> already() const;
|
||||
|
||||
~MembersInner();
|
||||
|
||||
signals:
|
||||
|
||||
void mustScrollTo(int ymin, int ymax);
|
||||
|
||||
void loaded();
|
||||
|
||||
public slots:
|
||||
|
||||
void updateSel();
|
||||
void peerUpdated(PeerData *peer);
|
||||
void onPeerNameChanged(PeerData *peer, const PeerData::Names &oldNames, const PeerData::NameFirstChars &oldChars);
|
||||
void onKickConfirm();
|
||||
void onKickBoxDestroyed(QObject *obj);
|
||||
|
||||
private:
|
||||
|
||||
void clearSel();
|
||||
MemberData *data(int32 index);
|
||||
|
||||
void membersReceived(const MTPchannels_ChannelParticipants &result, mtpRequestId req);
|
||||
bool membersFailed(const RPCError &error, mtpRequestId req);
|
||||
|
||||
void kickDone(const MTPUpdates &result, mtpRequestId req);
|
||||
void kickAdminDone(const MTPBool &result, mtpRequestId req);
|
||||
bool kickFail(const RPCError &error, mtpRequestId req);
|
||||
void removeKicked();
|
||||
|
||||
void clear();
|
||||
|
||||
ChannelData *_channel;
|
||||
MembersFilter _filter;
|
||||
|
||||
QString _kickText;
|
||||
int32 _time, _kickWidth;
|
||||
|
||||
int32 _sel, _kickSel, _kickDown;
|
||||
bool _mouseSel;
|
||||
|
||||
UserData *_kickConfirm;
|
||||
mtpRequestId _kickRequestId;
|
||||
|
||||
ConfirmBox *_kickBox;
|
||||
|
||||
enum MemberRole {
|
||||
MemberRoleNone,
|
||||
MemberRoleSelf,
|
||||
MemberRoleCreator,
|
||||
MemberRoleEditor,
|
||||
MemberRoleModerator,
|
||||
MemberRoleKicked
|
||||
};
|
||||
|
||||
struct MemberData {
|
||||
Text name;
|
||||
QString online;
|
||||
bool canKick;
|
||||
};
|
||||
|
||||
bool _loading;
|
||||
mtpRequestId _loadingRequestId;
|
||||
typedef QVector<UserData*> MemberRows;
|
||||
typedef QVector<QDateTime> MemberDates;
|
||||
typedef QVector<MemberRole> MemberRoles;
|
||||
typedef QVector<MemberData*> MemberDatas;
|
||||
MemberRows _rows;
|
||||
MemberDates _dates;
|
||||
MemberRoles _roles;
|
||||
MemberDatas _datas;
|
||||
|
||||
QPoint _lastMousePos;
|
||||
|
||||
};
|
||||
|
||||
class MembersBox : public ItemListBox {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
MembersBox(ChannelData *channel, MembersFilter filter);
|
||||
void keyPressEvent(QKeyEvent *e);
|
||||
void paintEvent(QPaintEvent *e);
|
||||
void resizeEvent(QResizeEvent *e);
|
||||
|
||||
void setInnerFocus() {
|
||||
setFocus();
|
||||
}
|
||||
|
||||
public slots:
|
||||
|
||||
void onLoaded();
|
||||
void onScroll();
|
||||
|
||||
void onAdd();
|
||||
void onAdminAdded();
|
||||
|
||||
protected:
|
||||
|
||||
void hideAll();
|
||||
void showAll();
|
||||
void showDone();
|
||||
|
||||
private:
|
||||
|
||||
MembersInner _inner;
|
||||
FlatButton _add, _done;
|
||||
|
||||
ContactsBox *_addBox;
|
||||
};
|
||||
|
||||
class NewGroupBox : public AbstractBox {
|
||||
Q_OBJECT
|
||||
|
||||
@ -319,6 +496,7 @@ public:
|
||||
void resizeEvent(QResizeEvent *e);
|
||||
void mouseMoveEvent(QMouseEvent *e);
|
||||
void mousePressEvent(QMouseEvent *e);
|
||||
void leaveEvent(QEvent *e);
|
||||
|
||||
void closePressed();
|
||||
|
||||
|
@ -105,7 +105,7 @@ _phone(phone), _fname(fname), _lname(lname), _replyTo(replyTo) {
|
||||
|
||||
_compressed.hide();
|
||||
|
||||
_name = _fname + QChar(' ') + _lname;
|
||||
_name = lng_full_name(lt_first_name, _fname, lt_last_name, _lname);
|
||||
_namew = st::mediaFont->m.width(_name);
|
||||
_size = _phone;
|
||||
_textw = qMax(_namew, st::mediaFont->m.width(_size));
|
||||
|
@ -228,25 +228,29 @@ void DialogsListWidget::paintEvent(QPaintEvent *e) {
|
||||
}
|
||||
}
|
||||
|
||||
void DialogsListWidget::peopleResultPaint(PeerData *peer, QPainter &p, int32 w, bool act, bool sel) const {
|
||||
void DialogsListWidget::peopleResultPaint(PeerData *peer, Painter &p, int32 w, bool act, bool sel) const {
|
||||
QRect fullRect(0, 0, w, st::dlgHeight);
|
||||
p.fillRect(fullRect, (act ? st::dlgActiveBG : (sel ? st::dlgHoverBG : st::dlgBG))->b);
|
||||
|
||||
History *history = App::history(peer->id);
|
||||
|
||||
p.drawPixmap(st::dlgPaddingHor, st::dlgPaddingVer, history->peer->photo->pix(st::dlgPhotoSize));
|
||||
p.drawPixmap(st::dlgPaddingHor, st::dlgPaddingVer, peer->photo->pix(st::dlgPhotoSize));
|
||||
|
||||
int32 nameleft = st::dlgPaddingHor + st::dlgPhotoSize + st::dlgPhotoPadding;
|
||||
int32 namewidth = w - nameleft - st::dlgPaddingHor;
|
||||
QRect rectForName(nameleft, st::dlgPaddingVer + st::dlgNameTop, namewidth, st::msgNameFont->height);
|
||||
|
||||
// draw chat icon
|
||||
if (history->peer->isChat()) {
|
||||
if (peer->isChat()) {
|
||||
p.drawPixmap(QPoint(rectForName.left() + st::dlgChatImgPos.x(), rectForName.top() + st::dlgChatImgPos.y()), App::sprite(), (act ? st::dlgActiveChatImg : st::dlgChatImg));
|
||||
rectForName.setLeft(rectForName.left() + st::dlgImgSkip);
|
||||
} else if (history->peer->isChannel()) {
|
||||
} else if (peer->isChannel()) {
|
||||
p.drawPixmap(QPoint(rectForName.left() + st::dlgChannelImgPos.x(), rectForName.top() + st::dlgChannelImgPos.y()), App::sprite(), (act ? st::dlgActiveChannelImg : st::dlgChannelImg));
|
||||
rectForName.setLeft(rectForName.left() + st::dlgImgSkip);
|
||||
if (peer->asChannel()->isVerified()) {
|
||||
rectForName.setWidth(rectForName.width() - st::verifiedCheck.pxWidth() - st::verifiedCheckPos.x());
|
||||
p.drawSprite(rectForName.topLeft() + QPoint(qMin(peer->dialogName().maxWidth(), rectForName.width()), 0) + st::verifiedCheckPos, (act ? st::verifiedCheckInv : st::verifiedCheck));
|
||||
}
|
||||
}
|
||||
|
||||
QRect tr(nameleft, st::dlgPaddingVer + st::dlgFont->height + st::dlgSep, namewidth, st::dlgFont->height);
|
||||
@ -273,7 +277,7 @@ void DialogsListWidget::peopleResultPaint(PeerData *peer, QPainter &p, int32 w,
|
||||
peer->dialogName().drawElided(p, rectForName.left(), rectForName.top(), rectForName.width());
|
||||
}
|
||||
|
||||
void DialogsListWidget::searchInPeerPaint(QPainter &p, int32 w) const {
|
||||
void DialogsListWidget::searchInPeerPaint(Painter &p, int32 w) const {
|
||||
QRect fullRect(0, 0, w, st::dlgHeight);
|
||||
p.fillRect(fullRect, st::dlgBG->b);
|
||||
|
||||
@ -450,6 +454,8 @@ void DialogsListWidget::removePeer(PeerData *peer) {
|
||||
History *history = App::history(peer->id);
|
||||
dialogs.del(peer);
|
||||
history->dialogs = History::DialogLinks();
|
||||
history->clearNotifications();
|
||||
if (App::wnd()) App::wnd()->notifyClear(history);
|
||||
if (contacts.list.rowByPeer.constFind(peer->id) != contacts.list.rowByPeer.cend()) {
|
||||
if (contactsNoDialogs.list.rowByPeer.constFind(peer->id) == contactsNoDialogs.list.rowByPeer.cend()) {
|
||||
contactsNoDialogs.addByName(App::history(peer->id));
|
||||
@ -1665,8 +1671,6 @@ void DialogsWidget::dialogsReceived(const MTPmessages_Dialogs &dialogs, mtpReque
|
||||
} break;
|
||||
}
|
||||
|
||||
unreadCountsReceived(*dlgList);
|
||||
|
||||
if (!_contactsRequest) {
|
||||
_contactsRequest = MTP::send(MTPcontacts_GetContacts(MTP_string("")), rpcDone(&DialogsWidget::contactsReceived), rpcFail(&DialogsWidget::contactsFailed));
|
||||
}
|
||||
@ -1674,6 +1678,7 @@ void DialogsWidget::dialogsReceived(const MTPmessages_Dialogs &dialogs, mtpReque
|
||||
if (_dialogsRequest == req) {
|
||||
_dialogsCount = count;
|
||||
if (dlgList) {
|
||||
unreadCountsReceived(*dlgList);
|
||||
list.dialogsReceived(*dlgList);
|
||||
onListScroll();
|
||||
|
||||
@ -1693,6 +1698,7 @@ void DialogsWidget::dialogsReceived(const MTPmessages_Dialogs &dialogs, mtpReque
|
||||
} else if (_channelDialogsRequest == req) {
|
||||
//_channelDialogsCount = count;
|
||||
if (dlgList) {
|
||||
unreadCountsReceived(*dlgList);
|
||||
list.dialogsReceived(*dlgList);
|
||||
onListScroll();
|
||||
|
||||
|
@ -49,8 +49,8 @@ public:
|
||||
void enterEvent(QEvent *e);
|
||||
void leaveEvent(QEvent *e);
|
||||
|
||||
void peopleResultPaint(PeerData *peer, QPainter &p, int32 w, bool act, bool sel) const;
|
||||
void searchInPeerPaint(QPainter &p, int32 w) const;
|
||||
void peopleResultPaint(PeerData *peer, Painter &p, int32 w, bool act, bool sel) const;
|
||||
void searchInPeerPaint(Painter &p, int32 w) const;
|
||||
|
||||
void selectSkip(int32 direction);
|
||||
void selectSkipPage(int32 pixels, int32 direction);
|
||||
|
@ -647,11 +647,12 @@ void ChannelHistory::addNewGroup(const MTPMessageGroup &group) {
|
||||
}
|
||||
|
||||
HistoryJoined *ChannelHistory::insertJoinedMessage(bool unread) {
|
||||
if (_joinedMessage || peer->asChannel()->haveLeft() || peer->asChannel()->wasKicked()) return _joinedMessage;
|
||||
if (_joinedMessage || !peer->asChannel()->amIn()) return _joinedMessage;
|
||||
|
||||
UserData *inviter = (peer->asChannel()->inviter > 0) ? App::userLoaded(peer->asChannel()->inviter) : 0;
|
||||
if (!inviter) return 0;
|
||||
|
||||
if (peerToUser(inviter->id) == MTP::authedId()) unread = false;
|
||||
int32 flags = (unread ? MTPDmessage_flag_unread : 0);
|
||||
QDateTime inviteDate = peer->asChannel()->inviteDate;
|
||||
if (unread) _maxReadMessageDate = inviteDate;
|
||||
@ -1725,8 +1726,11 @@ void History::newItemAdded(HistoryItem *item) {
|
||||
if (item->out()) {
|
||||
if (unreadBar) unreadBar->destroy();
|
||||
} else if (item->unread()) {
|
||||
notifies.push_back(item);
|
||||
App::main()->newUnreadMsg(this, item);
|
||||
bool skip = false;
|
||||
if (!isChannel() || peer->asChannel()->amIn()) {
|
||||
notifies.push_back(item);
|
||||
App::main()->newUnreadMsg(this, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2310,7 +2314,7 @@ void History::setLastMessage(HistoryItem *msg) {
|
||||
}
|
||||
|
||||
void History::setPosInDialogsDate(const QDateTime &date) {
|
||||
bool updateDialog = (App::main() && (!peer->isChannel() || peer->asChannel()->amCreator() || (!peer->asChannel()->haveLeft() && !peer->asChannel()->wasKicked())));
|
||||
bool updateDialog = (App::main() && (!peer->isChannel() || peer->asChannel()->amIn()));
|
||||
if (!lastMsgDate.isNull() && lastMsgDate >= date) {
|
||||
if (!updateDialog || !dialogs.isEmpty()) {
|
||||
return;
|
||||
@ -4493,7 +4497,24 @@ HistoryContact::HistoryContact(int32 userId, const QString &first, const QString
|
||||
App::regSharedContactPhone(userId, phone);
|
||||
|
||||
_maxw = st::mediaMaxWidth;
|
||||
name.setText(st::mediaFont, (first + ' ' + last).trimmed(), _textNameOptions);
|
||||
name.setText(st::mediaFont, lng_full_name(lt_first_name, first, lt_last_name, last).trimmed(), _textNameOptions);
|
||||
|
||||
phonew = st::mediaFont->m.width(phone);
|
||||
|
||||
if (contact) {
|
||||
contact->photo->load();
|
||||
}
|
||||
}
|
||||
|
||||
HistoryContact::HistoryContact(int32 userId, const QString &fullname, const QString &phone) : HistoryMedia(0)
|
||||
, userId(userId)
|
||||
, phone(App::formatPhone(phone))
|
||||
, contact(App::userLoaded(userId))
|
||||
{
|
||||
App::regSharedContactPhone(userId, phone);
|
||||
|
||||
_maxw = st::mediaMaxWidth;
|
||||
name.setText(st::mediaFont, fullname.trimmed(), _textNameOptions);
|
||||
|
||||
phonew = st::mediaFont->m.width(phone);
|
||||
|
||||
@ -4589,14 +4610,7 @@ void HistoryContact::getState(TextLinkPtr &lnk, HistoryCursorState &state, int32
|
||||
}
|
||||
|
||||
HistoryMedia *HistoryContact::clone() const {
|
||||
QStringList names = name.original(0, 0xFFFF, false).split(QChar(' '), QString::SkipEmptyParts);
|
||||
if (names.isEmpty()) {
|
||||
names.push_back(QString());
|
||||
}
|
||||
QString fname = names.front();
|
||||
names.pop_front();
|
||||
HistoryContact *result = new HistoryContact(userId, fname, names.join(QChar(' ')), phone);
|
||||
return result;
|
||||
return new HistoryContact(userId, name.original(0, 0xFFFF, false), phone);
|
||||
}
|
||||
|
||||
void HistoryContact::draw(Painter &p, const HistoryItem *parent, bool selected, int32 width) const {
|
||||
@ -5966,7 +5980,7 @@ void HistoryImageLink::getState(TextLinkPtr &lnk, HistoryCursorState &state, int
|
||||
skipx = st::mediaPadding.left();
|
||||
if (reply) {
|
||||
skipy = st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom();
|
||||
} if (fwd) {
|
||||
} else if (fwd) {
|
||||
skipy = st::msgServiceNameFont->height + st::msgPadding.top();
|
||||
}
|
||||
if (parent->displayFromName()) {
|
||||
|
@ -827,7 +827,7 @@ public:
|
||||
}
|
||||
bool unread() const {
|
||||
if ((out() && (id > 0 && id < _history->outboxReadBefore)) || (!out() && id > 0 && id < _history->inboxReadBefore)) return false;
|
||||
return (id > 0) ? true : (_flags & MTPDmessage_flag_unread);
|
||||
return (id > 0 && !out()) ? true : (_flags & MTPDmessage_flag_unread);
|
||||
}
|
||||
bool notifyByFrom() const {
|
||||
return _flags & MTPDmessage_flag_notify_by_from;
|
||||
@ -1332,6 +1332,7 @@ class HistoryContact : public HistoryMedia {
|
||||
public:
|
||||
|
||||
HistoryContact(int32 userId, const QString &first, const QString &last, const QString &phone);
|
||||
HistoryContact(int32 userId, const QString &fullname, const QString &phone);
|
||||
void initDimensions(const HistoryItem *parent);
|
||||
|
||||
void draw(Painter &p, const HistoryItem *parent, bool selected, int32 width) const;
|
||||
|
@ -3867,6 +3867,10 @@ bool HistoryWidget::joinFail(const RPCError &error, mtpRequestId req) {
|
||||
if (error.type().startsWith(qsl("FLOOD_WAIT_"))) return false;
|
||||
|
||||
if (_unblockRequest == req) _unblockRequest = 0;
|
||||
if (error.type() == qstr("CHANNEL_PRIVATE")) {
|
||||
App::wnd()->showLayer(new ConfirmBox(lang(lng_channel_not_accessible), true));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -4221,7 +4225,7 @@ void HistoryWidget::sendBotCommand(const QString &cmd, MsgId replyTo) { // reply
|
||||
|
||||
QString toSend = cmd;
|
||||
PeerData *bot = _peer->isUser() ? _peer : (App::hoveredLinkItem() ? (App::hoveredLinkItem()->toHistoryForwarded() ? App::hoveredLinkItem()->toHistoryForwarded()->fromForwarded() : App::hoveredLinkItem()->from()) : 0);
|
||||
if (!bot->isUser() || !bot->asUser()->botInfo) bot = 0;
|
||||
if (bot && (!bot->isUser() || !bot->asUser()->botInfo)) bot = 0;
|
||||
QString username = bot ? bot->asUser()->username : QString();
|
||||
int32 botStatus = _peer->isChat() ? _peer->asChat()->botStatus : (_peer->isChannel() ? _peer->asChannel()->botStatus : -1);
|
||||
if (!replyTo && toSend.indexOf('@') < 2 && !username.isEmpty() && (botStatus == 0 || botStatus == 2)) {
|
||||
@ -4352,7 +4356,7 @@ bool HistoryWidget::canSendMessages(PeerData *peer) const {
|
||||
} else if (peer->isChat()) {
|
||||
return !peer->asChat()->isForbidden && !peer->asChat()->haveLeft;
|
||||
} else if (peer->isChannel()) {
|
||||
return !peer->asChannel()->isForbidden && !peer->asChannel()->haveLeft() && !peer->asChannel()->wasKicked() && (peer->asChannel()->canPublish() || !peer->asChannel()->isBroadcast());
|
||||
return peer->asChannel()->amIn() && (peer->asChannel()->canPublish() || !peer->asChannel()->isBroadcast());
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@ -4376,7 +4380,7 @@ bool HistoryWidget::isBlocked() const {
|
||||
}
|
||||
|
||||
bool HistoryWidget::isJoinChannel() const {
|
||||
return _peer && _peer->isChannel() && !_peer->asChannel()->amParticipant();
|
||||
return _peer && _peer->isChannel() && !_peer->asChannel()->amIn();
|
||||
}
|
||||
|
||||
bool HistoryWidget::isMuteUnmute() const {
|
||||
|
@ -31,13 +31,18 @@ IntroSignup::IntroSignup(IntroWidget *parent) : IntroStage(parent),
|
||||
errorAlpha(0), a_photo(0),
|
||||
next(this, lang(lng_intro_finish), st::btnIntroNext),
|
||||
first(this, st::inpIntroName, lang(lng_signup_firstname)),
|
||||
last(this, st::inpIntroName, lang(lng_signup_lastname)) {
|
||||
last(this, st::inpIntroName, lang(lng_signup_lastname)),
|
||||
_invertOrder(langFirstNameGoesSecond()) {
|
||||
setVisible(false);
|
||||
setGeometry(parent->innerRect());
|
||||
|
||||
connect(&next, SIGNAL(clicked()), this, SLOT(onSubmitName()));
|
||||
connect(&checkRequest, SIGNAL(timeout()), this, SLOT(onCheckRequest()));
|
||||
|
||||
if (_invertOrder) {
|
||||
setTabOrder(&last, &first);
|
||||
}
|
||||
|
||||
setMouseTracking(true);
|
||||
}
|
||||
|
||||
@ -102,7 +107,12 @@ void IntroSignup::paintEvent(QPaintEvent *e) {
|
||||
if (animating() || error.length()) {
|
||||
p.setOpacity(errorAlpha.current());
|
||||
|
||||
QRect errRect((width() - st::introErrWidth) / 2, (last.y() + last.height() + next.y() - st::introErrHeight) / 2, st::introErrWidth, st::introErrHeight);
|
||||
QRect errRect;
|
||||
if (_invertOrder) {
|
||||
errRect = QRect((width() - st::introErrWidth) / 2, (first.y() + first.height() + next.y() - st::introErrHeight) / 2, st::introErrWidth, st::introErrHeight);
|
||||
} else {
|
||||
errRect = QRect((width() - st::introErrWidth) / 2, (last.y() + last.height() + next.y() - st::introErrHeight) / 2, st::introErrWidth, st::introErrHeight);
|
||||
}
|
||||
p.setFont(st::introErrFont->f);
|
||||
p.setPen(st::introErrColor->p);
|
||||
p.drawText(errRect, error, QTextOption(style::al_center));
|
||||
@ -135,8 +145,13 @@ void IntroSignup::resizeEvent(QResizeEvent *e) {
|
||||
_phTop = st::introTextTop + st::introTextSize.height() + st::introCountry.top;
|
||||
if (e->oldSize().width() != width()) {
|
||||
next.move((width() - next.width()) / 2, st::introBtnTop);
|
||||
first.move((width() - next.width()) / 2 + next.width() - first.width(), _phTop);
|
||||
last.move((width() - next.width()) / 2 + next.width() - last.width(), first.y() + st::introCountry.height + st::introCountry.ptrSize.height() + st::introPhoneTop);
|
||||
if (_invertOrder) {
|
||||
last.move((width() - next.width()) / 2 + next.width() - last.width(), _phTop);
|
||||
first.move((width() - next.width()) / 2 + next.width() - first.width(), last.y() + st::introCountry.height + st::introCountry.ptrSize.height() + st::introPhoneTop);
|
||||
} else {
|
||||
first.move((width() - next.width()) / 2 + next.width() - first.width(), _phTop);
|
||||
last.move((width() - next.width()) / 2 + next.width() - last.width(), first.y() + st::introCountry.height + st::introCountry.ptrSize.height() + st::introPhoneTop);
|
||||
}
|
||||
}
|
||||
textRect = QRect((width() - st::introTextSize.width()) / 2, st::introTextTop, st::introTextSize.width(), st::introTextSize.height());
|
||||
}
|
||||
@ -175,7 +190,11 @@ bool IntroSignup::animStep(float64 ms) {
|
||||
|
||||
void IntroSignup::activate() {
|
||||
show();
|
||||
first.setFocus();
|
||||
if (_invertOrder) {
|
||||
last.setFocus();
|
||||
} else {
|
||||
first.setFocus();
|
||||
}
|
||||
}
|
||||
|
||||
void IntroSignup::deactivate() {
|
||||
@ -196,7 +215,11 @@ void IntroSignup::onCheckRequest() {
|
||||
if (!first.isEnabled()) {
|
||||
first.setDisabled(false);
|
||||
last.setDisabled(false);
|
||||
last.setFocus();
|
||||
if (_invertOrder) {
|
||||
first.setFocus();
|
||||
} else {
|
||||
last.setFocus();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -241,7 +264,11 @@ bool IntroSignup::nameSubmitFail(const RPCError &error) {
|
||||
return true;
|
||||
} else if (error.type().startsWith(qsl("FLOOD_WAIT_"))) {
|
||||
showError(lang(lng_flood_error));
|
||||
last.setFocus();
|
||||
if (_invertOrder) {
|
||||
first.setFocus();
|
||||
} else {
|
||||
last.setFocus();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (cDebug()) { // internal server error
|
||||
@ -249,7 +276,11 @@ bool IntroSignup::nameSubmitFail(const RPCError &error) {
|
||||
} else {
|
||||
showError(lang(lng_server_error));
|
||||
}
|
||||
first.setFocus();
|
||||
if (_invertOrder) {
|
||||
last.setFocus();
|
||||
} else {
|
||||
first.setFocus();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -258,12 +289,22 @@ void IntroSignup::onInputChange() {
|
||||
}
|
||||
|
||||
void IntroSignup::onSubmitName(bool force) {
|
||||
if ((first.hasFocus() || first.text().trimmed().length()) && !last.text().trimmed().length()) {
|
||||
last.setFocus();
|
||||
return;
|
||||
} else if (!first.text().trimmed().length()) {
|
||||
first.setFocus();
|
||||
return;
|
||||
if (_invertOrder) {
|
||||
if ((last.hasFocus() || last.text().trimmed().length()) && !first.text().trimmed().length()) {
|
||||
first.setFocus();
|
||||
return;
|
||||
} else if (!last.text().trimmed().length()) {
|
||||
last.setFocus();
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if ((first.hasFocus() || first.text().trimmed().length()) && !last.text().trimmed().length()) {
|
||||
last.setFocus();
|
||||
return;
|
||||
} else if (!first.text().trimmed().length()) {
|
||||
first.setFocus();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!force && !first.isEnabled()) return;
|
||||
|
||||
|
@ -72,5 +72,7 @@ private:
|
||||
QString firstName, lastName;
|
||||
mtpRequestId sentRequest;
|
||||
|
||||
bool _invertOrder;
|
||||
|
||||
QTimer checkRequest;
|
||||
};
|
||||
|
@ -139,3 +139,19 @@ public:
|
||||
QString translate(const char *context, const char *sourceText, const char *disambiguation = 0, int n = -1) const;
|
||||
|
||||
};
|
||||
|
||||
inline bool langFirstNameGoesSecond() {
|
||||
QString fullname = lang(lng_full_name__tagged);
|
||||
for (const QChar *s = fullname.constData(), *ch = s, *e = ch + fullname.size(); ch != e;) {
|
||||
if (*ch == TextCommand) {
|
||||
if (ch + 3 < e && (ch + 1)->unicode() == TextCommandLangTag && *(ch + 3) == TextCommand) {
|
||||
if ((ch + 2)->unicode() == 0x0020 + lt_last_name) {
|
||||
return true;
|
||||
} else if ((ch + 2)->unicode() == 0x0020 + lt_first_name) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -864,7 +864,7 @@ void MainWidget::addParticipants(PeerData *chatOrChannel, const QVector<UserData
|
||||
for (QVector<UserData*>::const_iterator i = users.cbegin(), e = users.cend(); i != e; ++i) {
|
||||
inputUsers.push_back((*i)->inputUser);
|
||||
}
|
||||
MTP::send(MTPchannels_InviteToChannel(chatOrChannel->asChannel()->inputChannel, MTP_vector<MTPInputUser>(inputUsers)), rpcDone(&MainWidget::sentUpdatesReceived), rpcFail(&MainWidget::addParticipantsFail), 0, 5);
|
||||
MTP::send(MTPchannels_InviteToChannel(chatOrChannel->asChannel()->inputChannel, MTP_vector<MTPInputUser>(inputUsers)), rpcDone(&MainWidget::inviteToChannelDone, chatOrChannel->asChannel()), rpcFail(&MainWidget::addParticipantsFail), 0, 5);
|
||||
}
|
||||
}
|
||||
|
||||
@ -960,15 +960,13 @@ void MainWidget::checkedHistory(PeerData *peer, const MTPmessages_Messages &resu
|
||||
showDialogs();
|
||||
}
|
||||
} else if (peer->isChannel()) {
|
||||
if (peer->asChannel()->inviter > 0) {
|
||||
if (!peer->asChannel()->isForbidden && !peer->asChannel()->haveLeft() && !peer->asChannel()->wasKicked()) {
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -990,12 +988,10 @@ void MainWidget::checkedHistory(PeerData *peer, const MTPmessages_Messages &resu
|
||||
}
|
||||
}
|
||||
if (!h->lastMsgDate.isNull() && h->loadedAtBottom()) {
|
||||
if (peer->isChannel() && peer->asChannel()->inviter > 0 && h->lastMsgDate <= peer->asChannel()->inviteDate) {
|
||||
if (!peer->asChannel()->isForbidden && !peer->asChannel()->haveLeft() && !peer->asChannel()->wasKicked()) {
|
||||
if (UserData *from = App::userLoaded(peer->asChannel()->inviter)) {
|
||||
h->asChannelHistory()->insertJoinedMessage(true);
|
||||
history.peerMessagesUpdated(h->peer->id);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1264,8 +1260,12 @@ void MainWidget::saveRecentHashtags(const QString &text) {
|
||||
void MainWidget::readServerHistory(History *hist, bool force) {
|
||||
if (!hist || (!force && !hist->unreadCount)) return;
|
||||
|
||||
ReadRequests::const_iterator i = _readRequests.constFind(hist->peer);
|
||||
MsgId upTo = hist->inboxRead(0);
|
||||
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);
|
||||
if (i == _readRequests.cend()) {
|
||||
sendReadRequest(hist->peer, upTo);
|
||||
} else {
|
||||
@ -1670,7 +1670,7 @@ void MainWidget::messagesAffected(PeerData *peer, const MTPmessages_AffectedMess
|
||||
App::emitPeerUpdated();
|
||||
}
|
||||
}
|
||||
if (History *h = App::historyLoaded(peer->id)) {
|
||||
if (History *h = App::historyLoaded(peer ? peer->id : 0)) {
|
||||
if (!h->lastMsg) {
|
||||
checkPeerHistory(peer);
|
||||
}
|
||||
@ -2651,6 +2651,11 @@ void MainWidget::sentUpdatesReceived(uint64 randomId, const MTPUpdates &result)
|
||||
App::emitPeerUpdated();
|
||||
}
|
||||
|
||||
void MainWidget::inviteToChannelDone(ChannelData *channel, const MTPUpdates &updates) {
|
||||
sentUpdatesReceived(updates);
|
||||
channel->updateFull(true);
|
||||
}
|
||||
|
||||
void MainWidget::msgUpdated(PeerId peer, const HistoryItem *msg) {
|
||||
if (!msg) return;
|
||||
history.msgUpdated(peer, msg);
|
||||
@ -3504,6 +3509,8 @@ void MainWidget::openPeerByName(const QString &username, bool toProfile, const Q
|
||||
if (peer->isUser() && peer->asUser()->botInfo && !peer->asUser()->botInfo->cantJoinGroups && !startToken.isEmpty()) {
|
||||
peer->asUser()->botInfo->startGroupToken = startToken;
|
||||
App::wnd()->showLayer(new ContactsBox(peer->asUser()));
|
||||
} else if (peer->isChannel()) {
|
||||
showPeerHistory(peer->id, ShowAtUnreadMsgId);
|
||||
} else {
|
||||
showPeerProfile(peer);
|
||||
}
|
||||
@ -3574,6 +3581,8 @@ void MainWidget::usernameResolveDone(QPair<bool, QString> toProfileStartToken, c
|
||||
if (peer->isUser() && peer->asUser()->botInfo && !peer->asUser()->botInfo->cantJoinGroups && !toProfileStartToken.second.isEmpty()) {
|
||||
peer->asUser()->botInfo->startGroupToken = toProfileStartToken.second;
|
||||
App::wnd()->showLayer(new ContactsBox(peer->asUser()));
|
||||
} else if (peer->isChannel()) {
|
||||
showPeerHistory(peer->id, ShowAtUnreadMsgId);
|
||||
} else {
|
||||
showPeerProfile(peer);
|
||||
}
|
||||
@ -4504,7 +4513,7 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
|
||||
if (ChannelData *channel = App::channelLoaded(d.vchannel_id.v)) {
|
||||
App::markPeerUpdated(channel);
|
||||
channel->inviter = 0;
|
||||
if (channel->isForbidden || channel->wasKicked() || channel->haveLeft()) {
|
||||
if (!channel->amIn()) {
|
||||
dialogs.removePeer(channel);
|
||||
if (History *h = App::historyLoaded(channel->id)) {
|
||||
h->clear(true);
|
||||
|
@ -227,6 +227,7 @@ public:
|
||||
void sentUpdatesReceived(const MTPUpdates &updates) {
|
||||
return sentUpdatesReceived(0, updates);
|
||||
}
|
||||
void inviteToChannelDone(ChannelData *channel, const MTPUpdates &updates);
|
||||
void msgUpdated(PeerId peer, const HistoryItem *msg);
|
||||
void historyToDown(History *hist);
|
||||
void dialogsToUp();
|
||||
|
@ -44,13 +44,18 @@ namespace {
|
||||
MediaView *_view;
|
||||
};
|
||||
|
||||
|
||||
TextParseOptions _captionTextOptions = {
|
||||
TextParseLinks | TextParseMentions | TextParseHashtags | TextParseMultiline | TextParseRichText, // flags
|
||||
0, // maxw
|
||||
0, // maxh
|
||||
Qt::LayoutDirectionAuto, // dir
|
||||
};
|
||||
TextParseOptions _captionBotOptions = {
|
||||
TextParseLinks | TextParseMentions | TextParseHashtags | TextParseMultiline | TextParseRichText | TextParseBotCommands, // flags
|
||||
0, // maxw
|
||||
0, // maxh
|
||||
Qt::LayoutDirectionAuto, // dir
|
||||
};
|
||||
}
|
||||
|
||||
MediaView::MediaView() : TWidget(App::wnd()),
|
||||
@ -763,7 +768,7 @@ void MediaView::displayPhoto(PhotoData *photo, HistoryItem *item) {
|
||||
_caption = Text();
|
||||
if (HistoryMessage *itemMsg = item ? item->toHistoryMessage() : 0) {
|
||||
if (HistoryPhoto *photoMsg = dynamic_cast<HistoryPhoto*>(itemMsg->getMedia())) {
|
||||
_caption.setText(st::mvCaptionFont, photoMsg->captionForClone().original(0, 0xFFFF), _captionTextOptions);
|
||||
_caption.setText(st::mvCaptionFont, photoMsg->captionForClone().original(0, 0xFFFF), (item->from()->isUser() && item->from()->asUser()->botInfo) ? _captionBotOptions : _captionTextOptions);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -47,8 +47,9 @@ ProfileInner::ProfileInner(ProfileWidget *profile, ScrollArea *scroll, const Pee
|
||||
_invitationLink(this, qsl("telegram.me/joinchat/")),
|
||||
_botSettings(this, lang(lng_profile_bot_settings)),
|
||||
_botHelp(this, lang(lng_profile_bot_help)),
|
||||
_username(this, qsl("https://telegram.me/") + (_peerChannel ? _peerChannel->username : QString())),
|
||||
_editLink(this, lang((_peerChannel && _peerChannel->isPublic()) ? lng_profile_edit_public_link : lng_profile_create_public_link)),
|
||||
_username(this, (_peerChannel && _peerChannel->isPublic()) ? (qsl("telegram.me/") + _peerChannel->username) : lang(lng_profile_create_public_link)),
|
||||
_members(this, lng_channel_members_link(lt_count, (_peerChannel && _peerChannel->count > 0) ? _peerChannel->count : 1)),
|
||||
_admins(this, lng_channel_admins_link(lt_count, (_peerChannel && _peerChannel->adminsCount > 0) ? _peerChannel->adminsCount : 1)),
|
||||
|
||||
// about
|
||||
_about(st::wndMinWidth - st::profilePadding.left() - st::profilePadding.right()),
|
||||
@ -121,6 +122,8 @@ ProfileInner::ProfileInner(ProfileWidget *profile, ScrollArea *scroll, const Pee
|
||||
connect(&_createInvitationLink, SIGNAL(clicked()), this, SLOT(onCreateInvitationLink()));
|
||||
connect(&_invitationLink, SIGNAL(clicked()), this, SLOT(onInvitationLink()));
|
||||
connect(&_username, SIGNAL(clicked()), this, SLOT(onPublicLink()));
|
||||
connect(&_members, SIGNAL(clicked()), this, SLOT(onMembers()));
|
||||
connect(&_admins, SIGNAL(clicked()), this, SLOT(onAdmins()));
|
||||
_invitationLink.setAcceptBoth(true);
|
||||
_username.setAcceptBoth(true);
|
||||
updateInvitationLink();
|
||||
@ -128,7 +131,7 @@ ProfileInner::ProfileInner(ProfileWidget *profile, ScrollArea *scroll, const Pee
|
||||
if (_peerChat) {
|
||||
QString maxStr = lang(_uploadPhoto.textWidth() > _addParticipant.textWidth() ? lng_profile_set_group_photo : lng_profile_add_participant);
|
||||
_uploadPhoto.setAutoFontSize(st::profileMinBtnPadding, maxStr);
|
||||
_uploadPhoto.setAutoFontSize(st::profileMinBtnPadding, maxStr);
|
||||
_addParticipant.setAutoFontSize(st::profileMinBtnPadding, maxStr);
|
||||
} else if (_peerUser) {
|
||||
QString maxStr;
|
||||
if (_peerUser->botInfo && !_peerUser->botInfo->cantJoinGroups) {
|
||||
@ -141,11 +144,12 @@ ProfileInner::ProfileInner(ProfileWidget *profile, ScrollArea *scroll, const Pee
|
||||
_sendMessage.setAutoFontSize(st::profileMinBtnPadding, maxStr);
|
||||
_shareContact.setAutoFontSize(st::profileMinBtnPadding, maxStr);
|
||||
_inviteToGroup.setAutoFontSize(st::profileMinBtnPadding, maxStr);
|
||||
} else if (_peerChannel && _amCreator) {
|
||||
_uploadPhoto.setAutoFontSize(st::profileMinBtnPadding, lang(lng_profile_set_group_photo));
|
||||
}
|
||||
|
||||
connect(&_botSettings, SIGNAL(clicked()), this, SLOT(onBotSettings()));
|
||||
connect(&_botHelp, SIGNAL(clicked()), this, SLOT(onBotHelp()));
|
||||
connect(&_editLink, SIGNAL(clicked()), this, SLOT(onEditPublicLink()));
|
||||
|
||||
connect(App::app(), SIGNAL(peerPhotoDone(PeerId)), this, SLOT(onPhotoUpdateDone(PeerId)));
|
||||
connect(App::app(), SIGNAL(peerPhotoFail(PeerId)), this, SLOT(onPhotoUpdateFail(PeerId)));
|
||||
@ -340,9 +344,9 @@ bool ProfileInner::blockFail(const RPCError &error) {
|
||||
}
|
||||
|
||||
void ProfileInner::onAddParticipant() {
|
||||
if (!_peerChat && !_peerChannel) return;
|
||||
if (!_peerChat) return;
|
||||
|
||||
App::wnd()->showLayer(_peerChat ? (new ContactsBox(_peerChat)) : (new ContactsBox(_peerChannel)));
|
||||
App::wnd()->showLayer(new ContactsBox(_peerChat));
|
||||
}
|
||||
|
||||
void ProfileInner::onUpdatePhotoCancel() {
|
||||
@ -398,10 +402,24 @@ void ProfileInner::onInvitationLink() {
|
||||
}
|
||||
|
||||
void ProfileInner::onPublicLink() {
|
||||
if (!_peerChannel || !_peerChannel->isPublic()) return;
|
||||
if (!_peerChannel) return;
|
||||
|
||||
if (_peerChannel->isPublic()) {
|
||||
QApplication::clipboard()->setText(qsl("https://telegram.me/") + _peerChannel->username);
|
||||
App::wnd()->showLayer(new ConfirmBox(lang(lng_channel_public_link_copied), true));
|
||||
} else {
|
||||
App::wnd()->showLayer(new SetupChannelBox(_peerChannel, true));
|
||||
}
|
||||
}
|
||||
|
||||
QApplication::clipboard()->setText(qsl("https://telegram.me/") + _peerChannel->username);
|
||||
App::wnd()->showLayer(new ConfirmBox(lang(lng_channel_public_link_copied), true));
|
||||
void ProfileInner::onMembers() {
|
||||
if (!_peerChannel) return;
|
||||
App::wnd()->showLayer(new MembersBox(_peerChannel, MembersFilterRecent));
|
||||
}
|
||||
|
||||
void ProfileInner::onAdmins() {
|
||||
if (!_peerChannel) return;
|
||||
App::wnd()->showLayer(new MembersBox(_peerChannel, MembersFilterAdmins));
|
||||
}
|
||||
|
||||
void ProfileInner::onCreateInvitationLink() {
|
||||
@ -459,6 +477,9 @@ void ProfileInner::onFullPeerUpdated(PeerData *peer) {
|
||||
resizeEvent(0);
|
||||
} else if (_peerChannel) {
|
||||
updateInvitationLink();
|
||||
_members.setText(lng_channel_members_link(lt_count, (_peerChannel->count > 0) ? _peerChannel->count : 1));
|
||||
_admins.setText(lng_channel_admins_link(lt_count, (_peerChannel->adminsCount > 0) ? _peerChannel->adminsCount : 1));
|
||||
_onlineText = lng_chat_status_members(lt_count, _peerChannel->count > 0 ? _peerChannel->count : 1);
|
||||
if (_peerChannel->about.isEmpty()) {
|
||||
_about = Text(st::wndMinWidth - st::profilePadding.left() - st::profilePadding.right());
|
||||
} else {
|
||||
@ -497,10 +518,6 @@ void ProfileInner::onBotHelp() {
|
||||
updateBotLinksVisibility();
|
||||
}
|
||||
|
||||
void ProfileInner::onEditPublicLink() {
|
||||
App::wnd()->showLayer(new SetupChannelBox(_peerChannel, true), true);
|
||||
}
|
||||
|
||||
void ProfileInner::peerUpdated(PeerData *data) {
|
||||
if (data == _peer) {
|
||||
PhotoData *photo = 0;
|
||||
@ -518,6 +535,9 @@ void ProfileInner::peerUpdated(PeerData *data) {
|
||||
if (_peerChannel->isPublic() != _invitationLink.isHidden()) {
|
||||
peerUsernameChanged();
|
||||
}
|
||||
_members.setText(lng_channel_members_link(lt_count, (_peerChannel->count > 0) ? _peerChannel->count : 1));
|
||||
_admins.setText(lng_channel_admins_link(lt_count, (_peerChannel->adminsCount > 0) ? _peerChannel->adminsCount : 1));
|
||||
_onlineText = lng_chat_status_members(lt_count, _peerChannel->count > 0 ? _peerChannel->count : 1);
|
||||
}
|
||||
_photoLink = (photo && photo->date) ? TextLinkPtr(new PhotoLink(photo, _peer)) : TextLinkPtr();
|
||||
if (_peer->name != _nameCache) {
|
||||
@ -600,7 +620,7 @@ void ProfileInner::reorderParticipants() {
|
||||
if (_peerUser) {
|
||||
_onlineText = App::onlineText(_peerUser, t, true);
|
||||
} else if (_peerChannel) {
|
||||
_onlineText = _peerChannel->count ? lng_chat_status_members(lt_count, _peerChannel->count) : lang(lng_channel_status);
|
||||
_onlineText = lng_chat_status_members(lt_count, _peerChannel->count > 0 ? _peerChannel->count : 1);
|
||||
} else {
|
||||
_onlineText = lang(lng_chat_status_unaccessible);
|
||||
}
|
||||
@ -615,12 +635,7 @@ void ProfileInner::start() {
|
||||
|
||||
void ProfileInner::peerUsernameChanged() {
|
||||
if (_peerChannel) {
|
||||
if (_peerChannel->isPublic()) {
|
||||
_username.setText(qsl("https://telegram.me/") + _peerChannel->username);
|
||||
_editLink.setText(lang(lng_profile_edit_public_link));
|
||||
} else {
|
||||
_editLink.setText(lang(lng_profile_create_public_link));
|
||||
}
|
||||
_username.setText(_peerChannel->isPublic() ? (qsl("telegram.me/") + _peerChannel->username) : lang(lng_profile_create_public_link));
|
||||
resizeEvent(0);
|
||||
showAll();
|
||||
}
|
||||
@ -636,7 +651,7 @@ bool ProfileInner::event(QEvent *e) {
|
||||
}
|
||||
|
||||
void ProfileInner::paintEvent(QPaintEvent *e) {
|
||||
QPainter p(this);
|
||||
Painter p(this);
|
||||
|
||||
QRect r(e->rect());
|
||||
p.setClipRect(r);
|
||||
@ -657,8 +672,15 @@ void ProfileInner::paintEvent(QPaintEvent *e) {
|
||||
p.setOpacity(1);
|
||||
}
|
||||
}
|
||||
|
||||
int32 namew = _width - st::profilePhotoSize - st::profileNameLeft;
|
||||
p.setPen(st::black->p);
|
||||
_nameText.drawElided(p, _left + st::profilePhotoSize + st::profileNameLeft, top + st::profileNameTop, _width - st::profilePhotoSize - st::profileNameLeft);
|
||||
if (_peerChannel && _peerChannel->isVerified()) {
|
||||
namew -= st::verifiedCheckProfile.pxWidth() + st::verifiedCheckProfilePos.x();
|
||||
int32 cx = _left + st::profilePhotoSize + st::profileNameLeft + qMin(_nameText.maxWidth(), namew);
|
||||
p.drawSprite(QPoint(cx, top + st::profileNameTop) + st::verifiedCheckProfilePos, st::verifiedCheckProfile);
|
||||
}
|
||||
_nameText.drawElided(p, _left + st::profilePhotoSize + st::profileNameLeft, top + st::profileNameTop, namew);
|
||||
|
||||
p.setFont(st::profileStatusFont->f);
|
||||
int32 addbyname = 0;
|
||||
@ -666,24 +688,22 @@ void ProfileInner::paintEvent(QPaintEvent *e) {
|
||||
addbyname = st::profileStatusTop + st::linkFont->ascent - (st::profileNameTop + st::profileNameFont->ascent);
|
||||
p.setPen(st::black->p);
|
||||
p.drawText(_left + st::profilePhotoSize + st::profileStatusLeft, top + st::profileStatusTop + st::linkFont->ascent, '@' + _peerUser->username);
|
||||
} else if (_peerChannel && (_peerChannel->isPublic() || _amCreator)) {
|
||||
addbyname = st::profileStatusTop + st::linkFont->ascent - (st::profileNameTop + st::profileNameFont->ascent);
|
||||
}
|
||||
p.setPen((_peerUser && App::onlineColorUse(_peerUser, l_time) ? st::profileOnlineColor : st::profileOfflineColor)->p);
|
||||
p.drawText(_left + st::profilePhotoSize + st::profileStatusLeft, top + addbyname + st::profileStatusTop + st::linkFont->ascent, _onlineText);
|
||||
if (_amCreator && ((_peerChat && !_peerChat->invitationUrl.isEmpty()) || (_peerChannel && !_peerChannel->invitationUrl.isEmpty()))) {
|
||||
if (!_peerChannel || !_peerChannel->isPublic()) {
|
||||
p.setPen(st::black->p);
|
||||
p.drawText(_left + st::profilePhotoSize + st::profilePhoneLeft, _createInvitationLink.y() + st::linkFont->ascent, lang(lng_group_invite_link));
|
||||
}
|
||||
if (!_peerChannel || (!_amCreator && !_peerChannel->amEditor() && !_peerChannel->amModerator())) {
|
||||
p.setPen((_peerUser && App::onlineColorUse(_peerUser, l_time) ? st::profileOnlineColor : st::profileOfflineColor)->p);
|
||||
p.drawText(_left + st::profilePhotoSize + st::profileStatusLeft, top + addbyname + st::profileStatusTop + st::linkFont->ascent, _onlineText);
|
||||
}
|
||||
if (!_cancelPhoto.isHidden()) {
|
||||
p.setPen(st::profileOfflineColor->p);
|
||||
p.drawText(_left + st::profilePhotoSize + st::profilePhoneLeft, _cancelPhoto.y() + addbyname + st::linkFont->ascent, lang(lng_settings_uploading_photo));
|
||||
p.drawText(_left + st::profilePhotoSize + st::profilePhoneLeft, _cancelPhoto.y() + st::linkFont->ascent, lang(lng_settings_uploading_photo));
|
||||
}
|
||||
|
||||
if (!_errorText.isEmpty()) {
|
||||
p.setFont(st::setErrFont->f);
|
||||
p.setPen(st::setErrColor->p);
|
||||
p.drawText(_left + st::profilePhotoSize + st::profilePhoneLeft, _cancelPhoto.y() + addbyname + st::profilePhoneFont->ascent, _errorText);
|
||||
p.drawText(_left + st::profilePhotoSize + st::profilePhoneLeft, _cancelPhoto.y() + st::profilePhoneFont->ascent, _errorText);
|
||||
}
|
||||
if (!_phoneText.isEmpty()) {
|
||||
p.setPen(st::black->p);
|
||||
@ -702,20 +722,12 @@ void ProfileInner::paintEvent(QPaintEvent *e) {
|
||||
if (!_peerChannel || _amCreator) {
|
||||
top += _shareContact.height();
|
||||
}
|
||||
if (_peerChannel && (_amCreator || _peerChannel->isPublic())) {
|
||||
if (!_amCreator) {
|
||||
top += st::setLittleSkip;
|
||||
} else {
|
||||
top += st::setSectionSkip;
|
||||
}
|
||||
top += _editLink.height();
|
||||
}
|
||||
|
||||
// about
|
||||
if (!_about.isEmpty()) {
|
||||
p.setFont(st::profileHeaderFont->f);
|
||||
p.setPen(st::profileHeaderColor->p);
|
||||
p.drawText(_left + st::profileHeaderLeft, top + st::profileHeaderTop + st::profileHeaderFont->ascent, lang(lng_profile_about_section));
|
||||
p.drawText(_left + st::profileHeaderLeft, top + st::profileHeaderTop + st::profileHeaderFont->ascent, lang(_peerChannel ? lng_profile_description_section : lng_profile_about_section));
|
||||
top += st::profileHeaderSkip;
|
||||
|
||||
_about.draw(p, _left, top, _width);
|
||||
@ -728,6 +740,17 @@ void ProfileInner::paintEvent(QPaintEvent *e) {
|
||||
p.drawText(_left + st::profileHeaderLeft, top + st::profileHeaderTop + st::profileHeaderFont->ascent, lang(lng_profile_settings_section));
|
||||
top += st::profileHeaderSkip;
|
||||
|
||||
// invite link stuff
|
||||
if (_amCreator && (!_peerChannel || !_peerChannel->isPublic())) {
|
||||
if ((_peerChat && !_peerChat->invitationUrl.isEmpty()) || (_peerChannel && !_peerChannel->invitationUrl.isEmpty())) {
|
||||
p.setPen(st::black);
|
||||
p.setFont(st::linkFont);
|
||||
p.drawText(_left, _invitationLink.y() + st::linkFont->ascent, lang(lng_group_invite_link));
|
||||
top += _invitationLink.height() + st::setLittleSkip;
|
||||
}
|
||||
top += _createInvitationLink.height() + st::setSectionSkip;
|
||||
}
|
||||
|
||||
top += _enableNotifications.height();
|
||||
|
||||
// shared media
|
||||
@ -764,7 +787,7 @@ void ProfileInner::paintEvent(QPaintEvent *e) {
|
||||
if (_peerUser || _peerChat) {
|
||||
top += st::setLittleSkip + _clearHistory.height();
|
||||
}
|
||||
if (_peerUser || _peerChat || !_amCreator) {
|
||||
if (_peerUser || _peerChat || (_peerChannel->amIn() && !_amCreator)) {
|
||||
top += st::setLittleSkip + _deleteConversation.height();
|
||||
}
|
||||
if (_peerUser && peerToUser(_peerUser->id) != MTP::authedId()) {
|
||||
@ -874,7 +897,7 @@ void ProfileInner::updateSelected() {
|
||||
if (_peerUser || _peerChat) {
|
||||
partfrom = _clearHistory.y() + _clearHistory.height();
|
||||
}
|
||||
if (_peerUser || _peerChat || !_amCreator) {
|
||||
if (_peerUser || _peerChat || (_peerChannel->amIn() && !_amCreator)) {
|
||||
partfrom = _deleteConversation.y() + _deleteConversation.height();
|
||||
}
|
||||
partfrom += st::profileHeaderSkip;
|
||||
@ -1075,16 +1098,15 @@ void ProfileInner::resizeEvent(QResizeEvent *e) {
|
||||
|
||||
// profile
|
||||
top += st::profilePadding.top();
|
||||
int32 addbyname = 0;
|
||||
if (_peerChannel && (_amCreator || _peerChannel->isPublic())) {
|
||||
_username.move(_left + st::profilePhotoSize + st::profileStatusLeft, top + st::profileStatusTop);
|
||||
addbyname = st::profileStatusTop + st::linkFont->ascent - (st::profileNameTop + st::profileNameFont->ascent);
|
||||
}
|
||||
_members.move(_left + st::profilePhotoSize + st::profileStatusLeft, top + addbyname + st::profileStatusTop);
|
||||
addbyname = st::profileStatusTop + st::linkFont->ascent - (st::profileNameTop + st::profileNameFont->ascent);
|
||||
_admins.move(_left + st::profilePhotoSize + st::profileStatusLeft, top + 2 * addbyname + st::profileStatusTop);
|
||||
if (_amCreator) {
|
||||
if ((_peerChat && _peerChat->invitationUrl.isEmpty()) || (_peerChannel && _peerChannel->invitationUrl.isEmpty())) {
|
||||
_createInvitationLink.move(_left + st::profilePhotoSize + st::profilePhoneLeft, top + st::profilePhoneTop);
|
||||
} else {
|
||||
_createInvitationLink.move(_left + _width - _createInvitationLink.width(), top + st::profilePhoneTop);
|
||||
}
|
||||
if (!_invitationText.isEmpty()) {
|
||||
_invitationLink.setText(st::linkFont->m.elidedText(_invitationText, Qt::ElideRight, _width - st::profilePhotoSize - st::profilePhoneLeft));
|
||||
}
|
||||
_invitationLink.move(_left + st::profilePhotoSize + st::profilePhoneLeft, top + st::profilePhoneTop + st::linkFont->height * 1.2);
|
||||
_cancelPhoto.move(_left + _width - _cancelPhoto.width(), top + st::profilePhotoSize - st::linkFont->height);
|
||||
} else {
|
||||
_cancelPhoto.move(_left + _width - _cancelPhoto.width(), top + st::profilePhoneTop);
|
||||
@ -1105,20 +1127,6 @@ void ProfileInner::resizeEvent(QResizeEvent *e) {
|
||||
if (!_peerChannel || _amCreator) {
|
||||
top += _shareContact.height();
|
||||
}
|
||||
if (_peerChannel && (_amCreator || _peerChannel->isPublic())) {
|
||||
if (!_amCreator) {
|
||||
top += st::setLittleSkip;
|
||||
} else {
|
||||
top += st::setSectionSkip;
|
||||
}
|
||||
if (_peerChannel->isPublic()) {
|
||||
_username.move(_left, top);
|
||||
_editLink.move(_left + _width - _editLink.width(), top);
|
||||
} else {
|
||||
_editLink.move(_left, top);
|
||||
}
|
||||
top += _editLink.height();
|
||||
}
|
||||
|
||||
// about
|
||||
if (!_about.isEmpty()) {
|
||||
@ -1130,6 +1138,23 @@ void ProfileInner::resizeEvent(QResizeEvent *e) {
|
||||
|
||||
// settings
|
||||
top += st::profileHeaderSkip;
|
||||
|
||||
// invite link stuff
|
||||
int32 _inviteLinkTextWidth(st::linkFont->m.width(lang(lng_group_invite_link)) + st::linkFont->spacew);
|
||||
if (_amCreator && (!_peerChannel || !_peerChannel->isPublic())) {
|
||||
if (!_invitationText.isEmpty()) {
|
||||
_invitationLink.setText(st::linkFont->m.elidedText(_invitationText, Qt::ElideRight, _width - _inviteLinkTextWidth));
|
||||
}
|
||||
if ((_peerChat && !_peerChat->invitationUrl.isEmpty()) || (_peerChannel && !_peerChannel->invitationUrl.isEmpty())) {
|
||||
_invitationLink.move(_left + _inviteLinkTextWidth, top);
|
||||
top += _invitationLink.height() + st::setLittleSkip;
|
||||
_createInvitationLink.move(_left, top);
|
||||
} else {
|
||||
_createInvitationLink.move(_left, top);
|
||||
}
|
||||
top += _createInvitationLink.height() + st::setSectionSkip;
|
||||
}
|
||||
|
||||
_enableNotifications.move(_left, top); top += _enableNotifications.height();
|
||||
|
||||
// shared media
|
||||
@ -1157,7 +1182,7 @@ void ProfileInner::resizeEvent(QResizeEvent *e) {
|
||||
if (_peerUser || _peerChat) {
|
||||
_clearHistory.move(_left, top); top += _clearHistory.height() + st::setLittleSkip;
|
||||
}
|
||||
if (_peerUser || _peerChat || !_amCreator) {
|
||||
if (_peerUser || _peerChat || (_peerChannel->amIn() && !_amCreator)) {
|
||||
_deleteConversation.move(_left, top); top += _deleteConversation.height();
|
||||
}
|
||||
if (_peerUser && peerToUser(_peerUser->id) != MTP::authedId()) {
|
||||
@ -1288,8 +1313,10 @@ int32 ProfileInner::countMinHeight() {
|
||||
} else if (_peerChannel) {
|
||||
if (_amCreator) {
|
||||
h = _deleteChannel.y() + _deleteChannel.height() + st::profileHeaderSkip;
|
||||
} else {
|
||||
} else if (_peerChannel->amIn()) {
|
||||
h = _deleteConversation.y() + _deleteConversation.height() + st::profileHeaderSkip;
|
||||
} else {
|
||||
h = _searchInPeer.y() + _searchInPeer.height() + st::profileHeaderSkip;
|
||||
}
|
||||
}
|
||||
return h;
|
||||
@ -1309,7 +1336,7 @@ void ProfileInner::showAll() {
|
||||
} else {
|
||||
_clearHistory.hide();
|
||||
}
|
||||
if (_peerUser || _peerChat || !_amCreator) {
|
||||
if (_peerUser || _peerChat || (_peerChannel->amIn() && !_amCreator)) {
|
||||
_deleteConversation.show();
|
||||
} else {
|
||||
_deleteConversation.hide();
|
||||
@ -1339,8 +1366,9 @@ void ProfileInner::showAll() {
|
||||
_blockUser.hide();
|
||||
}
|
||||
_deleteChannel.hide();
|
||||
_editLink.hide();
|
||||
_username.hide();
|
||||
_members.hide();
|
||||
_admins.hide();
|
||||
} else if (_peerChat) {
|
||||
_sendMessage.hide();
|
||||
_shareContact.hide();
|
||||
@ -1378,8 +1406,9 @@ void ProfileInner::showAll() {
|
||||
}
|
||||
_blockUser.hide();
|
||||
_deleteChannel.hide();
|
||||
_editLink.hide();
|
||||
_username.hide();
|
||||
_members.hide();
|
||||
_admins.hide();
|
||||
} else if (_peerChannel) {
|
||||
_sendMessage.hide();
|
||||
_shareContact.hide();
|
||||
@ -1387,7 +1416,6 @@ void ProfileInner::showAll() {
|
||||
if (_peerChannel->isForbidden) {
|
||||
_uploadPhoto.hide();
|
||||
_cancelPhoto.hide();
|
||||
_addParticipant.hide();
|
||||
_createInvitationLink.hide();
|
||||
_invitationLink.hide();
|
||||
} else {
|
||||
@ -1413,25 +1441,26 @@ void ProfileInner::showAll() {
|
||||
_createInvitationLink.hide();
|
||||
_invitationLink.hide();
|
||||
}
|
||||
if (_amCreator) {
|
||||
_addParticipant.show();
|
||||
} else {
|
||||
_addParticipant.hide();
|
||||
}
|
||||
}
|
||||
_addParticipant.hide();
|
||||
_blockUser.hide();
|
||||
if (_amCreator) {
|
||||
_deleteChannel.show();
|
||||
_editLink.show();
|
||||
} else {
|
||||
_deleteChannel.hide();
|
||||
_editLink.hide();
|
||||
}
|
||||
if (_peerChannel->isPublic()) {
|
||||
if (_peerChannel->isPublic() || _amCreator) {
|
||||
_username.show();
|
||||
} else {
|
||||
_username.hide();
|
||||
}
|
||||
if (_amCreator || _peerChannel->amEditor() || _peerChannel->amModerator()) {
|
||||
_members.show();
|
||||
_admins.show();
|
||||
} else {
|
||||
_members.hide();
|
||||
_admins.hide();
|
||||
}
|
||||
}
|
||||
_enableNotifications.show();
|
||||
updateNotifySettings();
|
||||
|
@ -110,11 +110,13 @@ public slots:
|
||||
void onCreateInvitationLinkSure();
|
||||
void onPublicLink();
|
||||
|
||||
void onMembers();
|
||||
void onAdmins();
|
||||
|
||||
void onFullPeerUpdated(PeerData *peer);
|
||||
|
||||
void onBotSettings();
|
||||
void onBotHelp();
|
||||
void onEditPublicLink();
|
||||
|
||||
private:
|
||||
|
||||
@ -146,7 +148,7 @@ private:
|
||||
FlatButton _sendMessage, _shareContact, _inviteToGroup;
|
||||
LinkButton _cancelPhoto, _createInvitationLink, _invitationLink;
|
||||
QString _invitationText;
|
||||
LinkButton _botSettings, _botHelp, _username, _editLink;
|
||||
LinkButton _botSettings, _botHelp, _username, _members, _admins;
|
||||
|
||||
Text _about;
|
||||
int32 _aboutTop, _aboutHeight;
|
||||
|
@ -2107,7 +2107,6 @@ bool psShowOpenWithMenu(int x, int y, const QString &file) {
|
||||
if (sel > 0) {
|
||||
if (sel <= handlers.size()) {
|
||||
IDataObject *dataObj = 0;
|
||||
IEnumAssocHandlers *assocHandlers = 0;
|
||||
if (SUCCEEDED(pItem->BindToHandler(nullptr, BHID_DataObject, IID_PPV_ARGS(&dataObj))) && dataObj) {
|
||||
handlers.at(sel - 1).handler->Invoke(dataObj);
|
||||
dataObj->Release();
|
||||
|
@ -129,7 +129,17 @@ void PeerData::updateName(const QString &newName, const QString &newNameOrPhone,
|
||||
asUser()->username = newUsername;
|
||||
asUser()->setNameOrPhone(newNameOrPhone);
|
||||
} else if (isChannel()) {
|
||||
asChannel()->username = newUsername;
|
||||
if (asChannel()->username != newUsername) {
|
||||
asChannel()->username = newUsername;
|
||||
if (newUsername.isEmpty()) {
|
||||
asChannel()->flags &= ~MTPDchannel::flag_username;
|
||||
} else {
|
||||
asChannel()->flags |= MTPDchannel::flag_username;
|
||||
}
|
||||
if (App::main()) {
|
||||
App::main()->peerUsernameChanged(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Names oldNames = names;
|
||||
@ -207,7 +217,7 @@ void UserData::setName(const QString &first, const QString &last, const QString
|
||||
firstName = first;
|
||||
lastName = last;
|
||||
}
|
||||
updateName(lastName.isEmpty() ? firstName : (firstName + ' ' + lastName), phoneName, usern);
|
||||
updateName(lastName.isEmpty() ? firstName : lng_full_name(lt_first_name, firstName, lt_last_name, lastName), phoneName, usern);
|
||||
}
|
||||
if (updUsername) {
|
||||
if (App::main()) {
|
||||
@ -383,20 +393,10 @@ void ChannelData::setName(const QString &newName, const QString &usern) {
|
||||
bool updName = !newName.isEmpty(), updUsername = (username != usern);
|
||||
|
||||
updateName(newName.isEmpty() ? name : newName, QString(), usern);
|
||||
if (updUsername) {
|
||||
if (usern.isEmpty()) {
|
||||
flags &= ~MTPDchannel::flag_username;
|
||||
} else {
|
||||
flags |= MTPDchannel::flag_username;
|
||||
}
|
||||
if (App::main()) {
|
||||
App::main()->peerUsernameChanged(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ChannelData::updateFull() {
|
||||
if (!_lastFullUpdate || getms(true) > _lastFullUpdate + UpdateFullChannelTimeout) {
|
||||
void ChannelData::updateFull(bool force) {
|
||||
if (!_lastFullUpdate || force || getms(true) > _lastFullUpdate + UpdateFullChannelTimeout) {
|
||||
App::api()->requestFullPeer(this);
|
||||
if (!amCreator() && !inviter) App::api()->requestSelfParticipant(this);
|
||||
}
|
||||
@ -959,7 +959,7 @@ id(id), type(type), url(url), displayUrl(displayUrl), siteName(siteName), title(
|
||||
void PeerLink::onClick(Qt::MouseButton button) const {
|
||||
if (button == Qt::LeftButton && App::main()) {
|
||||
if (peer() && peer()->isChannel() && App::main()->historyPeer() != peer()) {
|
||||
if (!peer()->asChannel()->isPublic() && (peer()->asChannel()->isForbidden || peer()->asChannel()->haveLeft() || peer()->asChannel()->wasKicked())) {
|
||||
if (!peer()->asChannel()->isPublic() && !peer()->asChannel()->amIn()) {
|
||||
App::wnd()->showLayer(new ConfirmBox(lang(lng_channel_not_accessible), true));
|
||||
} else {
|
||||
App::main()->showPeerHistory(peer()->id, ShowAtUnreadMsgId);
|
||||
|
@ -451,13 +451,13 @@ private:
|
||||
class ChannelData : public PeerData {
|
||||
public:
|
||||
|
||||
ChannelData(const PeerId &id) : PeerData(id), access(0), inputChannel(MTP_inputChannel(MTP_int(bareId()), MTP_long(0))), count(0), date(0), version(0), isForbidden(true), botStatus(-1), inviter(0), _lastFullUpdate(0) {
|
||||
ChannelData(const PeerId &id) : PeerData(id), access(0), inputChannel(MTP_inputChannel(MTP_int(bareId()), MTP_long(0))), count(1), adminsCount(1), date(0), version(0), isForbidden(true), botStatus(-1), inviter(0), _lastFullUpdate(0) {
|
||||
setName(QString(), QString());
|
||||
}
|
||||
void setPhoto(const MTPChatPhoto &photo, const PhotoId &phId = UnknownPeerPhotoId);
|
||||
void setName(const QString &name, const QString &username);
|
||||
|
||||
void updateFull();
|
||||
void updateFull(bool force = false);
|
||||
void fullUpdated();
|
||||
|
||||
uint64 access;
|
||||
@ -466,7 +466,7 @@ public:
|
||||
|
||||
QString username, about;
|
||||
|
||||
int32 count;
|
||||
int32 count, adminsCount;
|
||||
int32 date;
|
||||
int32 version;
|
||||
int32 flags;
|
||||
@ -491,13 +491,16 @@ public:
|
||||
bool wasKicked() const {
|
||||
return flags & MTPDchannel_flag_was_kicked;
|
||||
}
|
||||
bool amIn() const {
|
||||
return !isForbidden && !haveLeft() && !wasKicked();
|
||||
}
|
||||
bool canPublish() const {
|
||||
return amCreator() || amEditor();
|
||||
}
|
||||
bool amParticipant() const {
|
||||
return canPublish() || (!haveLeft() && !wasKicked());
|
||||
}
|
||||
bool isForbidden;
|
||||
bool isVerified() const {
|
||||
return flags & MTPDchannel_flag_is_verified;
|
||||
}
|
||||
|
||||
int32 botStatus; // -1 - no bots, 0 - unknown, 1 - one bot, that sees all history, 2 - other
|
||||
// ImagePtr photoFull;
|
||||
|
Loading…
Reference in New Issue
Block a user