diff --git a/Telegram/Resources/lang.txt b/Telegram/Resources/lang.txt index a31af65ec..9ad9a9e22 100644 --- a/Telegram/Resources/lang.txt +++ b/Telegram/Resources/lang.txt @@ -134,6 +134,9 @@ lng_dlg_conversations: "Conversations"; lng_dlg_messages: "Messages"; lng_dlg_new_group_name: "Group name"; lng_dlg_create_group: "Create"; +lng_no_contacts: "You have no contacts"; +lng_contacts_loading: "Loading.."; +lng_contacts_not_found: "No contacts found"; lng_settings_profile: "Profile"; lng_settings_edit: "Edit"; @@ -155,6 +158,8 @@ Minimum length is 5 characters."; lng_username_invalid: "This name is invalid."; lng_username_occupied: "This name is already occupied."; lng_username_too_short: "This name is too short."; +lng_username_bad_symbols: "This name has bad symbols."; +lng_username_available: "This name is available."; lng_settings_section_contact_info: "Contact info"; lng_settings_phone_number: "Phone number:"; diff --git a/Telegram/Resources/style.txt b/Telegram/Resources/style.txt index 030b0c9bb..5983cb977 100644 --- a/Telegram/Resources/style.txt +++ b/Telegram/Resources/style.txt @@ -535,6 +535,7 @@ setErrBG: #ffa5a5; setErrColor: #800000; setErrHeight: 30px; setErrFont: font(fsize); +setGoodColor: #008000; btnSetUpload: flatButton(btnDefNext, btnDefBig) { width: 206px; @@ -598,22 +599,9 @@ dlgPaddingVer: 8px; dlgHeight: 62px; dlgPhotoPadding: 12px; -dlgState: switcher { - border: 2px; - borderColor: btnNextBG; - - bgColor: #fff; - bgHovered: btnWhiteHover; - bgActive: btnNextBG; - - height: 34px; - - font: font(fsize); - textColor: btnYesColor; - activeColor: #fff; - - duration: 200; -} +noContactsHeight: 100px; +noContactsFont: font(fsize); +noContactsColor: #777; dlgSep: 8px; diff --git a/Telegram/SourceFiles/art/icon2.ico b/Telegram/SourceFiles/art/icon2.ico deleted file mode 100644 index 498c8b8f8..000000000 Binary files a/Telegram/SourceFiles/art/icon2.ico and /dev/null differ diff --git a/Telegram/SourceFiles/boxes/addparticipantbox.cpp b/Telegram/SourceFiles/boxes/addparticipantbox.cpp index 9dd608367..773d6dc5a 100644 --- a/Telegram/SourceFiles/boxes/addparticipantbox.cpp +++ b/Telegram/SourceFiles/boxes/addparticipantbox.cpp @@ -23,19 +23,26 @@ Copyright (c) 2014 John Preston, https://tdesktop.com #include "window.h" AddParticipantInner::AddParticipantInner(ChatData *chat) : _chat(chat), - _contacts(&App::main()->contactsList()), _sel(0), _filteredSel(-1), _mouseSel(false), _selCount(0) { - - _filter = qsl("a"); - updateFilter(); +_contacts(&App::main()->contactsList()), +_sel(0), +_filteredSel(-1), +_mouseSel(false), +_selCount(0), +_addContactLnk(this, lang(lng_add_contact_button)) { + + connect(&_addContactLnk, SIGNAL(clicked()), App::wnd(), SLOT(onShowAddContact())); for (DialogRow *r = _contacts->list.begin; r != _contacts->list.end; r = r->next) { r->attached = 0; } - connect(App::main(), SIGNAL(dialogRowReplaced(DialogRow *, DialogRow *)), this, SLOT(onDialogRowReplaced(DialogRow *, DialogRow *))); - connect(App::main(), SIGNAL(peerUpdated(PeerData*)), this, SLOT(peerUpdated(PeerData *))); - connect(App::main(), SIGNAL(peerNameChanged(PeerData *, const PeerData::Names &, const PeerData::NameFirstChars &)), this, SLOT(peerUpdated(PeerData *))); - connect(App::main(), SIGNAL(peerPhotoChanged(PeerData *)), this, SLOT(peerUpdated(PeerData *))); + _filter = qsl("a"); + updateFilter(); + + connect(App::main(), SIGNAL(dialogRowReplaced(DialogRow*,DialogRow*)), this, SLOT(onDialogRowReplaced(DialogRow*,DialogRow*))); + connect(App::main(), SIGNAL(peerUpdated(PeerData*)), this, SLOT(peerUpdated(PeerData*))); + connect(App::main(), SIGNAL(peerNameChanged(PeerData*,const PeerData::Names&,const PeerData::NameFirstChars&)), this, SLOT(peerUpdated(PeerData*))); + connect(App::main(), SIGNAL(peerPhotoChanged(PeerData*)), this, SLOT(peerUpdated(PeerData*))); } void AddParticipantInner::peerUpdated(PeerData *peer) { @@ -184,11 +191,15 @@ void AddParticipantInner::paintEvent(QPaintEvent *e) { drawFrom = drawFrom->next; } } else { - // .. + p.setFont(st::noContactsFont->f); + p.setPen(st::noContactsColor->p); + p.drawText(QRect(0, 0, width(), st::noContactsHeight - (cContactsReceived() ? st::noContactsFont->height : 0)), lang(cContactsReceived() ? lng_no_contacts : lng_contacts_loading), style::al_center); } } else { if (_filtered.isEmpty()) { - // .. + p.setFont(st::noContactsFont->f); + p.setPen(st::noContactsColor->p); + p.drawText(QRect(0, 0, width(), st::noContactsHeight), lang(lng_contacts_not_found), style::al_center); } else { int32 from = yFrom / rh; if (from < 0) from = 0; @@ -312,14 +323,23 @@ void AddParticipantInner::updateFilter(QString filter) { int32 rh = (st::profileListPhotoSize + st::profileListPadding.height() * 2); _filter = filter; if (_filter.isEmpty()) { - resize(width(), _contacts->list.count * rh); if (_contacts->list.count) { + if (!_addContactLnk.isHidden()) _addContactLnk.hide(); + resize(width(), _contacts->list.count * rh); _sel = _contacts->list.begin; while (_sel->next->next &&& contactData(_sel)->inchat) { _sel = _sel->next; } + } else { + resize(width(), st::noContactsHeight); + if (cContactsReceived()) { + if (_addContactLnk.isHidden()) _addContactLnk.show(); + } else { + if (!_addContactLnk.isHidden()) _addContactLnk.hide(); + } } } else { + if (!_addContactLnk.isHidden()) _addContactLnk.hide(); QStringList::const_iterator fb = f.cbegin(), fe = f.cend(), fi; _filtered.clear(); @@ -365,7 +385,11 @@ void AddParticipantInner::updateFilter(QString filter) { ++_filteredSel; } - resize(width(), _filtered.size() * rh); + if (!_filtered.isEmpty()) { + resize(width(), _filtered.size() * rh); + } else { + resize(width(), st::noContactsHeight); + } } if (parentWidget()) parentWidget()->update(); loadProfilePhotos(0); @@ -406,6 +430,10 @@ AddParticipantInner::~AddParticipantInner() { } } +void AddParticipantInner::resizeEvent(QResizeEvent *e) { + _addContactLnk.move((width() - _addContactLnk.width()) / 2, (st::noContactsHeight + st::noContactsFont->height) / 2); +} + void AddParticipantInner::selectSkip(int32 dir) { _time = unixtime(); _mouseSel = false; @@ -520,7 +548,7 @@ AddParticipantBox::AddParticipantBox(ChatData *chat) : connect(&_scroll, SIGNAL(scrolled()), &_inner, SLOT(updateSel())); connect(&_scroll, SIGNAL(scrolled()), this, SLOT(onScroll())); connect(&_filter, SIGNAL(changed()), this, SLOT(onFilterUpdate())); - connect(&_filter, SIGNAL(cancelled()), this, SIGNAL(onClose())); + connect(&_filter, SIGNAL(cancelled()), this, SLOT(onClose())); connect(&_inner, SIGNAL(mustScrollTo(int,int)), &_scroll, SLOT(scrollToY(int,int))); connect(&_inner, SIGNAL(selectAllQuery()), &_filter, SLOT(selectAll())); @@ -578,6 +606,7 @@ void AddParticipantBox::paintEvent(QPaintEvent *e) { // paint shadows p.fillRect(0, st::participantFilter.height, _width, st::scrollDef.topsh, st::scrollDef.shColor->b); + p.fillRect(0, size().height() - st::btnSelectCancel.height - st::scrollDef.bottomsh, _width, st::scrollDef.bottomsh, st::scrollDef.shColor->b); // paint button sep p.fillRect(st::btnSelectCancel.width, size().height() - st::btnSelectCancel.height, st::lineWidth, st::btnSelectCancel.height, st::btnSelectSep->b); diff --git a/Telegram/SourceFiles/boxes/addparticipantbox.h b/Telegram/SourceFiles/boxes/addparticipantbox.h index 8f797997b..515d5ff89 100644 --- a/Telegram/SourceFiles/boxes/addparticipantbox.h +++ b/Telegram/SourceFiles/boxes/addparticipantbox.h @@ -31,6 +31,7 @@ public: void leaveEvent(QEvent *e); void mouseMoveEvent(QMouseEvent *e); void mousePressEvent(QMouseEvent *e); + void resizeEvent(QResizeEvent *e); void paintDialog(QPainter &p, DialogRow *row, bool sel); void updateFilter(QString filter = QString()); @@ -87,6 +88,7 @@ private: ContactData *contactData(DialogRow *row); QPoint _lastMousePos; + LinkButton _addContactLnk; }; diff --git a/Telegram/SourceFiles/boxes/contactsbox.cpp b/Telegram/SourceFiles/boxes/contactsbox.cpp index c98c83c4e..0b78723f6 100644 --- a/Telegram/SourceFiles/boxes/contactsbox.cpp +++ b/Telegram/SourceFiles/boxes/contactsbox.cpp @@ -23,14 +23,22 @@ Copyright (c) 2014 John Preston, https://tdesktop.com #include "mainwidget.h" #include "window.h" -ContactsInner::ContactsInner() : _contacts(&App::main()->contactsList()), _sel(0), _filteredSel(-1), _mouseSel(false) { - _filter = qsl("a"); - updateFilter(); +ContactsInner::ContactsInner() : +_contacts(&App::main()->contactsList()), +_sel(0), +_filteredSel(-1), +_mouseSel(false), +_addContactLnk(this, lang(lng_add_contact_button)) { + + connect(&_addContactLnk, SIGNAL(clicked()), App::wnd(), SLOT(onShowAddContact())); for (DialogRow *r = _contacts->list.begin; r != _contacts->list.end; r = r->next) { r->attached = 0; } + _filter = qsl("a"); + updateFilter(); + connect(App::main(), SIGNAL(dialogRowReplaced(DialogRow *, DialogRow *)), this, SLOT(onDialogRowReplaced(DialogRow *, DialogRow *))); connect(App::main(), SIGNAL(peerUpdated(PeerData*)), this, SLOT(peerUpdated(PeerData *))); connect(App::main(), SIGNAL(peerNameChanged(PeerData *, const PeerData::Names &, const PeerData::NameFirstChars &)), this, SLOT(peerUpdated(PeerData *))); @@ -153,11 +161,15 @@ void ContactsInner::paintEvent(QPaintEvent *e) { drawFrom = drawFrom->next; } } else { - // .. + p.setFont(st::noContactsFont->f); + p.setPen(st::noContactsColor->p); + p.drawText(QRect(0, 0, width(), st::noContactsHeight - (cContactsReceived() ? st::noContactsFont->height : 0)), lang(cContactsReceived() ? lng_no_contacts : lng_contacts_loading), style::al_center); } } else { if (_filtered.isEmpty()) { - // .. + p.setFont(st::noContactsFont->f); + p.setPen(st::noContactsColor->p); + p.drawText(QRect(0, 0, width(), st::noContactsHeight), lang(lng_contacts_not_found), style::al_center); } else { int32 from = yFrom / rh; if (from < 0) from = 0; @@ -255,11 +267,20 @@ void ContactsInner::updateFilter(QString filter) { int32 rh = (st::profileListPhotoSize + st::profileListPadding.height() * 2); _filter = filter; if (_filter.isEmpty()) { - resize(width(), _contacts->list.count * rh + st::contactsClose.height); if (_contacts->list.count) { + if (!_addContactLnk.isHidden()) _addContactLnk.hide(); + resize(width(), _contacts->list.count * rh + st::contactsClose.height); _sel = _contacts->list.begin; + } else { + resize(width(), st::noContactsHeight); + if (cContactsReceived()) { + if (_addContactLnk.isHidden()) _addContactLnk.show(); + } else { + if (!_addContactLnk.isHidden()) _addContactLnk.hide(); + } } } else { + if (!_addContactLnk.isHidden()) _addContactLnk.hide(); QStringList::const_iterator fb = f.cbegin(), fe = f.cend(), fi; _filtered.clear(); @@ -302,7 +323,11 @@ void ContactsInner::updateFilter(QString filter) { } _filteredSel = _filtered.isEmpty() ? -1 : 0; - resize(width(), _filtered.size() * rh + st::contactsClose.height); + if (!_filtered.isEmpty()) { + resize(width(), _filtered.size() * rh + st::contactsClose.height); + } else { + resize(width(), st::noContactsHeight); + } } if (parentWidget()) parentWidget()->update(); loadProfilePhotos(0); @@ -333,7 +358,8 @@ void ContactsInner::onDialogRowReplaced(DialogRow *oldRow, DialogRow *newRow) { } _mouseSel = false; int32 rh = (st::profileListPhotoSize + st::profileListPadding.height() * 2); - int32 newh = (_filter.isEmpty() ? _contacts->list.count : _filtered.size()) * rh; + int32 cnt = (_filter.isEmpty() ? _contacts->list.count : _filtered.size()); + int32 newh = cnt ? (cnt * rh + st::contactsClose.height) : st::noContactsHeight; resize(width(), newh); } @@ -343,6 +369,10 @@ ContactsInner::~ContactsInner() { } } +void ContactsInner::resizeEvent(QResizeEvent *e) { + _addContactLnk.move((width() - _addContactLnk.width()) / 2, (st::noContactsHeight + st::noContactsFont->height) / 2); +} + void ContactsInner::selectSkip(int32 dir) { _mouseSel = false; int32 rh = st::profileListPhotoSize + st::profileListPadding.height() * 2, origDir = dir; @@ -409,12 +439,12 @@ ContactsBox::ContactsBox() : _scroll(this, st::newGroupScroll), _inner(), _scroll.setWidget(&_inner); _scroll.setFocusPolicy(Qt::NoFocus); - connect(&_addContact, SIGNAL(clicked()), this, SLOT(onAdd())); + connect(&_addContact, SIGNAL(clicked()), App::wnd(), SLOT(onShowAddContact())); connect(&_close, SIGNAL(clicked()), this, SLOT(onClose())); connect(&_scroll, SIGNAL(scrolled()), &_inner, SLOT(updateSel())); connect(&_scroll, SIGNAL(scrolled()), this, SLOT(onScroll())); connect(&_filter, SIGNAL(changed()), this, SLOT(onFilterUpdate())); - connect(&_filter, SIGNAL(cancelled()), this, SIGNAL(onClose())); + connect(&_filter, SIGNAL(cancelled()), this, SLOT(onClose())); connect(&_inner, SIGNAL(mustScrollTo(int,int)), &_scroll, SLOT(scrollToY(int,int))); showAll(); diff --git a/Telegram/SourceFiles/boxes/contactsbox.h b/Telegram/SourceFiles/boxes/contactsbox.h index 5fb4b01ac..fd92859c9 100644 --- a/Telegram/SourceFiles/boxes/contactsbox.h +++ b/Telegram/SourceFiles/boxes/contactsbox.h @@ -31,6 +31,7 @@ public: void leaveEvent(QEvent *e); void mouseMoveEvent(QMouseEvent *e); void mousePressEvent(QMouseEvent *e); + void resizeEvent(QResizeEvent *e); void paintDialog(QPainter &p, DialogRow *row, bool sel); void updateFilter(QString filter = QString()); @@ -77,6 +78,7 @@ private: ContactData *contactData(DialogRow *row); QPoint _lastMousePos; + LinkButton _addContactLnk; }; diff --git a/Telegram/SourceFiles/boxes/newgroupbox.cpp b/Telegram/SourceFiles/boxes/newgroupbox.cpp index ad6674371..667a5689b 100644 --- a/Telegram/SourceFiles/boxes/newgroupbox.cpp +++ b/Telegram/SourceFiles/boxes/newgroupbox.cpp @@ -22,7 +22,19 @@ Copyright (c) 2014 John Preston, https://tdesktop.com #include "mainwidget.h" #include "window.h" -NewGroupInner::NewGroupInner() : _contacts(&App::main()->contactsList()), _sel(0), _filteredSel(-1), _mouseSel(false), _selCount(0) { +NewGroupInner::NewGroupInner() : +_contacts(&App::main()->contactsList()), +_sel(0), +_filteredSel(-1), +_mouseSel(false), +_selCount(0), +_addContactLnk(this, lang(lng_add_contact_button)) { + + connect(&_addContactLnk, SIGNAL(clicked()), App::wnd(), SLOT(onShowAddContact())); + + for (DialogRow *r = _contacts->list.begin; r != _contacts->list.end; r = r->next) { + r->attached = 0; + } _filter = qsl("a"); updateFilter(); @@ -165,11 +177,15 @@ void NewGroupInner::paintEvent(QPaintEvent *e) { drawFrom = drawFrom->next; } } else { - // .. + p.setFont(st::noContactsFont->f); + p.setPen(st::noContactsColor->p); + p.drawText(QRect(0, 0, width(), st::noContactsHeight - (cContactsReceived() ? st::noContactsFont->height : 0)), lang(cContactsReceived() ? lng_no_contacts : lng_contacts_loading), style::al_center); } } else { if (_filtered.isEmpty()) { - // .. + p.setFont(st::noContactsFont->f); + p.setPen(st::noContactsColor->p); + p.drawText(QRect(0, 0, width(), st::noContactsHeight), lang(lng_contacts_not_found), style::al_center); } else { int32 from = yFrom / rh; if (from < 0) from = 0; @@ -279,9 +295,19 @@ void NewGroupInner::updateFilter(QString filter) { if (_filter.isEmpty()) { resize(width(), _contacts->list.count * rh); if (_contacts->list.count) { + if (!_addContactLnk.isHidden()) _addContactLnk.hide(); + resize(width(), _contacts->list.count * rh); _sel = _contacts->list.begin; + } else { + resize(width(), st::noContactsHeight); + if (cContactsReceived()) { + if (_addContactLnk.isHidden()) _addContactLnk.show(); + } else { + if (!_addContactLnk.isHidden()) _addContactLnk.hide(); + } } } else { + if (!_addContactLnk.isHidden()) _addContactLnk.hide(); QStringList::const_iterator fb = f.cbegin(), fe = f.cend(), fi; _filtered.clear(); @@ -324,7 +350,11 @@ void NewGroupInner::updateFilter(QString filter) { } _filteredSel = _filtered.isEmpty() ? -1 : 0; - resize(width(), _filtered.size() * rh); + if (!_filtered.isEmpty()) { + resize(width(), _filtered.size() * rh); + } else { + resize(width(), st::noContactsHeight); + } } if (parentWidget()) parentWidget()->update(); loadProfilePhotos(0); @@ -365,6 +395,10 @@ NewGroupInner::~NewGroupInner() { } } +void NewGroupInner::resizeEvent(QResizeEvent *e) { + _addContactLnk.move((width() - _addContactLnk.width()) / 2, (st::noContactsHeight + st::noContactsFont->height) / 2); +} + void NewGroupInner::selectSkip(int32 dir) { _mouseSel = false; int32 rh = st::profileListPhotoSize + st::profileListPadding.height() * 2, origDir = dir; @@ -456,7 +490,7 @@ NewGroupBox::NewGroupBox() : _scroll(this, st::newGroupScroll), _inner(), connect(&_scroll, SIGNAL(scrolled()), &_inner, SLOT(updateSel())); connect(&_scroll, SIGNAL(scrolled()), this, SLOT(onScroll())); connect(&_filter, SIGNAL(changed()), this, SLOT(onFilterUpdate())); - connect(&_filter, SIGNAL(cancelled()), this, SIGNAL(onClose())); + connect(&_filter, SIGNAL(cancelled()), this, SLOT(onClose())); connect(&_inner, SIGNAL(mustScrollTo(int,int)), &_scroll, SLOT(scrollToY(int,int))); connect(&_inner, SIGNAL(selectAllQuery()), &_filter, SLOT(selectAll())); @@ -518,6 +552,7 @@ void NewGroupBox::paintEvent(QPaintEvent *e) { // paint shadows p.fillRect(0, st::participantFilter.height, _width, st::scrollDef.topsh, st::scrollDef.shColor->b); + p.fillRect(0, size().height() - st::btnSelectCancel.height - st::scrollDef.bottomsh, _width, st::scrollDef.bottomsh, st::scrollDef.shColor->b); // paint button sep p.fillRect(st::btnSelectCancel.width, size().height() - st::btnSelectCancel.height, st::lineWidth, st::btnSelectCancel.height, st::btnSelectSep->b); diff --git a/Telegram/SourceFiles/boxes/newgroupbox.h b/Telegram/SourceFiles/boxes/newgroupbox.h index 7cb856eca..2cbb15357 100644 --- a/Telegram/SourceFiles/boxes/newgroupbox.h +++ b/Telegram/SourceFiles/boxes/newgroupbox.h @@ -31,7 +31,8 @@ public: void leaveEvent(QEvent *e); void mouseMoveEvent(QMouseEvent *e); void mousePressEvent(QMouseEvent *e); - + void resizeEvent(QResizeEvent *e); + void paintDialog(QPainter &p, DialogRow *row, bool sel); void updateFilter(QString filter = QString()); @@ -85,6 +86,7 @@ private: ContactData *contactData(DialogRow *row); QPoint _lastMousePos; + LinkButton _addContactLnk; }; diff --git a/Telegram/SourceFiles/boxes/usernamebox.cpp b/Telegram/SourceFiles/boxes/usernamebox.cpp index e3274849a..f37a67cb0 100644 --- a/Telegram/SourceFiles/boxes/usernamebox.cpp +++ b/Telegram/SourceFiles/boxes/usernamebox.cpp @@ -28,24 +28,23 @@ UsernameInput::UsernameInput(QWidget *parent, const style::flatInput &st, const void UsernameInput::correctValue(QKeyEvent *e, const QString &was) { QString oldText(text()), newText; - int32 oldPos(cursorPosition()), newPos(-1), oldLen(oldText.length()); - newText.reserve(oldLen); - - for (int32 i = 0; i < oldLen; ++i) { - if (i == oldPos) { - newPos = newText.length(); + int32 newPos = cursorPosition(), from, len = oldText.size(); + for (from = 0; from < len; ++from) { + if (!oldText.at(from).isSpace()) { + break; } - - QChar ch = oldText[i]; - if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9') || ch == '_' || (ch == '@' && !i)) { - if (newText.size() < MaxUsernameLength) { - newText.append(ch); - } + if (newPos > 0) --newPos; + } + len -= from; + if (len > MaxUsernameLength) len = MaxUsernameLength + (oldText.at(from) == '@' ? 1 : 0); + for (int32 to = from + len; to > from;) { + --to; + if (!oldText.at(to).isSpace()) { + break; } + --len; } - if (newPos < 0) { - newPos = newText.length(); - } + newText = oldText.mid(from, len); if (newText != oldText) { setText(newText); setCursorPosition(newPos); @@ -59,6 +58,7 @@ _usernameInput(this, st::inpAddContact, qsl("@username"), App::self()->username) _saveRequest(0), _checkRequest(0), _about(st::usernameWidth - 2 * st::addContactTitlePos.x()), a_opacity(0, 1), _hiding(false) { _about.setRichText(st::usernameFont, lang(lng_username_about)); + _goodText = App::self()->username.isEmpty() ? QString() : lang(lng_username_available); initBox(); } @@ -135,6 +135,11 @@ void UsernameBox::paintEvent(QPaintEvent *e) { p.setFont(st::setErrFont->f); int32 w = st::setErrFont->m.width(_errorText); p.drawText((_width - w) / 2, _usernameInput.y() + _usernameInput.height() + ((st::usernameSkip - st::setErrFont->height) / 2) + st::setErrFont->ascent, _errorText); + } else if (!_goodText.isEmpty()) { + p.setPen(st::setGoodColor->p); + p.setFont(st::setErrFont->f); + int32 w = st::setErrFont->m.width(_goodText); + p.drawText((_width - w) / 2, _usernameInput.y() + _usernameInput.height() + ((st::usernameSkip - st::setErrFont->height) / 2) + st::setErrFont->ascent, _goodText); } p.setPen(st::usernameColor->p); _about.draw(p, st::addContactTitlePos.x(), _usernameInput.y() + _usernameInput.height() + st::usernameSkip, width() - 2 * st::addContactTitlePos.x()); @@ -180,23 +185,37 @@ void UsernameBox::onCheck() { void UsernameBox::onChanged() { QString name = getName(); if (name.isEmpty()) { - if (!_errorText.isEmpty()) { - _errorText = QString(); - update(); - } - _checkTimer.stop(); - } else if (name.size() < MinUsernameLength) { - if (_errorText != lang(lng_username_too_short)) { - _errorText = lang(lng_username_too_short); + if (!_errorText.isEmpty() || !_goodText.isEmpty()) { + _errorText = _goodText = QString(); update(); } _checkTimer.stop(); } else { - if (!_errorText.isEmpty()) { - _errorText = QString(); - update(); + int32 i, len = name.size(); + for (int32 i = 0; i < len; ++i) { + QChar ch = name.at(i); + if ((ch < 'A' || ch > 'Z') && (ch < 'a' || ch > 'z') && (ch < '0' || ch > '9') && ch != '_' && (ch != '@' || i > 0)) { + if (_errorText != lang(lng_username_bad_symbols)) { + _errorText = lang(lng_username_bad_symbols); + update(); + } + _checkTimer.stop(); + return; + } + } + if (name.size() < MinUsernameLength) { + if (_errorText != lang(lng_username_too_short)) { + _errorText = lang(lng_username_too_short); + update(); + } + _checkTimer.stop(); + } else { + if (!_errorText.isEmpty() || !_goodText.isEmpty()) { + _errorText = _goodText = QString(); + update(); + } + _checkTimer.start(UsernameCheckTimeout); } - _checkTimer.start(UsernameCheckTimeout); } } @@ -230,8 +249,10 @@ bool UsernameBox::onUpdateFail(const RPCError &error) { void UsernameBox::onCheckDone(const MTPBool &result) { _checkRequest = 0; QString newError = (result.v || _checkUsername == App::self()->username) ? QString() : lang(lng_username_occupied); - if (_errorText != newError) { + QString newGood = newError.isEmpty() ? lang(lng_username_available) : QString(); + if (_errorText != newError || _goodText != newGood) { _errorText = newError; + _goodText = newGood; update(); } } @@ -248,6 +269,7 @@ bool UsernameBox::onCheckFail(const RPCError &error) { update(); return true; } + _goodText = QString(); _usernameInput.setFocus(); return true; } diff --git a/Telegram/SourceFiles/boxes/usernamebox.h b/Telegram/SourceFiles/boxes/usernamebox.h index 3ea1aef5c..e96c62f62 100644 --- a/Telegram/SourceFiles/boxes/usernamebox.h +++ b/Telegram/SourceFiles/boxes/usernamebox.h @@ -72,7 +72,7 @@ private: QPixmap _cache; mtpRequestId _saveRequest, _checkRequest; - QString _sentUsername, _checkUsername, _errorText; + QString _sentUsername, _checkUsername, _errorText, _goodText; Text _about; QTimer _checkTimer; diff --git a/Telegram/SourceFiles/dialogswidget.cpp b/Telegram/SourceFiles/dialogswidget.cpp index 62f1fa137..89e11c9d9 100644 --- a/Telegram/SourceFiles/dialogswidget.cpp +++ b/Telegram/SourceFiles/dialogswidget.cpp @@ -26,11 +26,25 @@ Copyright (c) 2014 John Preston, https://tdesktop.com #include "boxes/newgroupbox.h" DialogsListWidget::DialogsListWidget(QWidget *parent, MainWidget *main) : QWidget(parent), -dialogs(false), contactsNoDialogs(true), contacts(true), sel(0), contactSel(false), selByMouse(false), filteredSel(-1), searchedCount(0), searchedSel(-1), peopleSel(-1), _lastSearchId(0), _state(DefaultState) { - connect(main, SIGNAL(dialogToTop(const History::DialogLinks &)), this, SLOT(onDialogToTop(const History::DialogLinks &))); - connect(main, SIGNAL(peerNameChanged(PeerData *, const PeerData::Names &, const PeerData::NameFirstChars &)), this, SLOT(onPeerNameChanged(PeerData *, const PeerData::Names &, const PeerData::NameFirstChars &))); - connect(main, SIGNAL(peerPhotoChanged(PeerData *)), this, SLOT(onPeerPhotoChanged(PeerData *))); - connect(main, SIGNAL(dialogRowReplaced(DialogRow *, DialogRow *)), this, SLOT(onDialogRowReplaced(DialogRow *, DialogRow *))); +dialogs(false), +contactsNoDialogs(true), +contacts(true), +sel(0), +contactSel(false), +selByMouse(false), +filteredSel(-1), +searchedCount(0), +searchedSel(-1), +peopleSel(-1), +_lastSearchId(0), +_state(DefaultState), +_addContactLnk(this, lang(lng_add_contact_button)) { + connect(main, SIGNAL(dialogToTop(const History::DialogLinks&)), this, SLOT(onDialogToTop(const History::DialogLinks&))); + connect(main, SIGNAL(peerNameChanged(PeerData*,const PeerData::Names&,const PeerData::NameFirstChars&)), this, SLOT(onPeerNameChanged(PeerData*,const PeerData::Names&,const PeerData::NameFirstChars&))); + connect(main, SIGNAL(peerPhotoChanged(PeerData*)), this, SLOT(onPeerPhotoChanged(PeerData*))); + connect(main, SIGNAL(dialogRowReplaced(DialogRow*,DialogRow*)), this, SLOT(onDialogRowReplaced(DialogRow*,DialogRow*))); + connect(&_addContactLnk, SIGNAL(clicked()), App::wnd(), SLOT(onShowAddContact())); + refresh(false); } void DialogsListWidget::paintEvent(QPaintEvent *e) { @@ -51,7 +65,9 @@ void DialogsListWidget::paintEvent(QPaintEvent *e) { if (contactsNoDialogs.list.count) { contactsNoDialogs.list.paint(p, width(), r.top() - otherStart, r.bottom() - otherStart, active, selected); } else if (!otherStart) { - // .. paint no dialogs found + p.setFont(st::noContactsFont->f); + p.setPen(st::noContactsColor->p); + p.drawText(QRect(0, 0, width(), st::noContactsHeight - (cContactsReceived() ? st::noContactsFont->height : 0)), lang(cContactsReceived() ? lng_no_contacts : lng_contacts_loading), style::al_center); } } else if (_state == FilteredState || _state == SearchedState) { if (filterResults.isEmpty()) { @@ -255,6 +271,10 @@ void DialogsListWidget::mousePressEvent(QMouseEvent *e) { } } +void DialogsListWidget::resizeEvent(QResizeEvent *e) { + _addContactLnk.move((width() - _addContactLnk.width()) / 2, (st::noContactsHeight + st::noContactsFont->height) / 2); +} + void DialogsListWidget::onDialogRowReplaced(DialogRow *oldRow, DialogRow *newRow) { if (_state == FilteredState || _state == SearchedState) { for (FilteredDialogs::iterator i = filterResults.begin(); i != filterResults.end();) { @@ -615,6 +635,7 @@ void DialogsListWidget::peopleReceived(const QString &query, const QVector &contacts) { + cSetContactsReceived(true); for (QVector::const_iterator i = contacts.cbegin(), e = contacts.cend(); i != e; ++i) { addNewContact(i->c_contact().vuser_id.v); } @@ -652,10 +673,23 @@ void DialogsListWidget::refresh(bool toTop) { int32 h = 0; if (_state == DefaultState) { h = (dialogs.list.count + contactsNoDialogs.list.count) * st::dlgHeight; - } else if (_state == FilteredState) { - h = (filterResults.count() + peopleResults.count() + searchResults.count()) * st::dlgHeight + (peopleResults.isEmpty() ? 0 : st::searchedBarHeight) + (searchResults.isEmpty() ? 0 : st::searchedBarHeight); - } else if (_state == SearchedState) { - h = (filterResults.count() + peopleResults.count() + searchResults.count()) * st::dlgHeight + (peopleResults.isEmpty() ? 0 : st::searchedBarHeight) + st::searchedBarHeight; + if (h) { + if (!_addContactLnk.isHidden()) _addContactLnk.hide(); + } else { + h = st::noContactsHeight; + if (cContactsReceived()) { + if (_addContactLnk.isHidden()) _addContactLnk.show(); + } else { + if (!_addContactLnk.isHidden()) _addContactLnk.hide(); + } + } + } else { + if (!_addContactLnk.isHidden()) _addContactLnk.hide(); + if (_state == FilteredState) { + h = (filterResults.count() + peopleResults.count() + searchResults.count()) * st::dlgHeight + (peopleResults.isEmpty() ? 0 : st::searchedBarHeight) + (searchResults.isEmpty() ? 0 : st::searchedBarHeight); + } else if (_state == SearchedState) { + h = (filterResults.count() + peopleResults.count() + searchResults.count()) * st::dlgHeight + (peopleResults.isEmpty() ? 0 : st::searchedBarHeight) + st::searchedBarHeight; + } } resize(width(), h); if (toTop) { @@ -1607,7 +1641,7 @@ DialogsIndexed &DialogsWidget::contactsList() { } void DialogsWidget::onAddContact() { - App::wnd()->showLayer(new AddContactBox()); + App::wnd()->replaceLayer(new AddContactBox()); } void DialogsWidget::onNewGroup() { diff --git a/Telegram/SourceFiles/dialogswidget.h b/Telegram/SourceFiles/dialogswidget.h index bf7575a4a..30b4ca013 100644 --- a/Telegram/SourceFiles/dialogswidget.h +++ b/Telegram/SourceFiles/dialogswidget.h @@ -39,6 +39,7 @@ public: void paintEvent(QPaintEvent *e); void mouseMoveEvent(QMouseEvent *e); void mousePressEvent(QMouseEvent *e); + void resizeEvent(QResizeEvent *e); void enterEvent(QEvent *e); void leaveEvent(QEvent *e); @@ -139,6 +140,8 @@ private: void paintDialog(QPainter &p, DialogRow *dialog); + LinkButton _addContactLnk; + }; class DialogsWidget : public QWidget, public Animated, public RPCSender { diff --git a/Telegram/SourceFiles/layerwidget.cpp b/Telegram/SourceFiles/layerwidget.cpp index e969f4d4a..f08177961 100644 --- a/Telegram/SourceFiles/layerwidget.cpp +++ b/Telegram/SourceFiles/layerwidget.cpp @@ -64,18 +64,19 @@ void BackgroundWidget::onClose() { startHide(); } -void BackgroundWidget::onInnerClose() { - if (_hidden) { - w->deleteLater(); - w = _hidden; - _hidden = 0; - w->show(); - resizeEvent(0); - w->animStep(1); - update(); - } else { +bool BackgroundWidget::onInnerClose() { + if (!_hidden) { onClose(); + return true; } + w->deleteLater(); + w = _hidden; + _hidden = 0; + w->show(); + resizeEvent(0); + w->animStep(1); + update(); + return false; } void BackgroundWidget::startHide() { diff --git a/Telegram/SourceFiles/layerwidget.h b/Telegram/SourceFiles/layerwidget.h index 7ed6e69c6..f361ab9b9 100644 --- a/Telegram/SourceFiles/layerwidget.h +++ b/Telegram/SourceFiles/layerwidget.h @@ -68,7 +68,7 @@ public: public slots: void onClose(); - void onInnerClose(); + bool onInnerClose(); private: diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index 34cca9118..2ebccea28 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -769,6 +769,10 @@ void MainWidget::checkLastUpdate(bool afterSleep) { } } +void MainWidget::showAddContact() { + dialogs.onAddContact(); +} + void MainWidget::showNewGroup() { dialogs.onNewGroup(); } diff --git a/Telegram/SourceFiles/mainwidget.h b/Telegram/SourceFiles/mainwidget.h index 11ec68232..96fa4eebf 100644 --- a/Telegram/SourceFiles/mainwidget.h +++ b/Telegram/SourceFiles/mainwidget.h @@ -285,6 +285,7 @@ public: void peerUsernameChanged(PeerData *peer); void checkLastUpdate(bool afterSleep); + void showAddContact(); void showNewGroup(); ~MainWidget(); diff --git a/Telegram/SourceFiles/mtproto/mtpConnection.cpp b/Telegram/SourceFiles/mtproto/mtpConnection.cpp index 9193aed81..562c3684a 100644 --- a/Telegram/SourceFiles/mtproto/mtpConnection.cpp +++ b/Telegram/SourceFiles/mtproto/mtpConnection.cpp @@ -1090,7 +1090,6 @@ MTProtoConnectionPrivate::MTProtoConnectionPrivate(QThread *thread, MTProtoConne oldConnectionTimer.moveToThread(thread); connCheckTimer.moveToThread(thread); retryTimer.moveToThread(thread); - pinger.moveToThread(thread); moveToThread(thread); // createConn(); @@ -1118,10 +1117,22 @@ MTProtoConnectionPrivate::MTProtoConnectionPrivate(QThread *thread, MTProtoConne connect(this, SIGNAL(needToReceive()), sessionData->owner(), SLOT(tryToReceive()), Qt::QueuedConnection); connect(this, SIGNAL(stateChanged(qint32)), sessionData->owner(), SLOT(onConnectionStateChange(qint32)), Qt::QueuedConnection); connect(sessionData->owner(), SIGNAL(needToSend()), this, SLOT(tryToSend()), Qt::QueuedConnection); - connect(this, SIGNAL(needToSendAsync()), sessionData->owner(), SIGNAL(needToSend()), Qt::QueuedConnection); - connect(this, SIGNAL(sendHttpWait()), sessionData->owner(), SLOT(sendHttpWait()), Qt::QueuedConnection); connect(this, SIGNAL(sessionResetDone()), sessionData->owner(), SLOT(onResetDone()), Qt::QueuedConnection); + + static bool _registered = false; + if (!_registered) { + _registered = true; + qRegisterMetaType>("QVector"); + } + + connect(this, SIGNAL(needToSendAsync()), sessionData->owner(), SIGNAL(needToSend()), Qt::QueuedConnection); connect(this, SIGNAL(sendAnythingAsync(quint64)), sessionData->owner(), SLOT(sendAnything(quint64)), Qt::QueuedConnection); + connect(this, SIGNAL(sendHttpWaitAsync()), sessionData->owner(), SLOT(sendHttpWait()), Qt::QueuedConnection); + connect(this, SIGNAL(sendPongAsync(quint64,quint64)), sessionData->owner(), SLOT(sendPong(quint64,quint64)), Qt::QueuedConnection); + connect(this, SIGNAL(sendMsgsStateInfoAsync(quint64, QByteArray)), sessionData->owner(), SLOT(sendMsgsStateInfo(quint64,QByteArray)), Qt::QueuedConnection); + connect(this, SIGNAL(resendAsync(quint64,quint64,bool,bool)), sessionData->owner(), SLOT(resend(quint64,quint64,bool,bool)), Qt::QueuedConnection); + connect(this, SIGNAL(resendManyAsync(QVector,quint64,bool,bool)), sessionData->owner(), SLOT(resendMany(QVector,quint64,bool,bool)), Qt::QueuedConnection); + connect(this, SIGNAL(resendAllAsync()), sessionData->owner(), SLOT(resendAll())); } void MTProtoConnectionPrivate::onConfigLoaded() { @@ -1809,7 +1820,6 @@ void MTProtoConnectionPrivate::doDisconnect() { unlockKey(); - pinger.stop(); clearAuthKeyData(); setState(MTProtoConnection::Disconnected); @@ -1914,7 +1924,7 @@ void MTProtoConnectionPrivate::handleReceived() { sessionData->setSalt(serverSalt); if (setState(MTProtoConnection::Connected, MTProtoConnection::Connecting)) { // only connected if (restarted) { - sessionData->owner()->resendAll(); + emit resendAllAsync(); restarted = false; } } @@ -1987,7 +1997,7 @@ void MTProtoConnectionPrivate::handleReceived() { } } if (conn->needHttpWait()) { - emit sendHttpWait(); + emit sendHttpWaitAsync(); } } @@ -2165,7 +2175,7 @@ int32 MTProtoConnectionPrivate::handleOneReceived(const mtpPrime *from, const mt if (setState(MTProtoConnection::Connected, MTProtoConnection::Connecting)) { // maybe only connected if (restarted) { - sessionData->owner()->resendAll(); + emit resendAllAsync(); restarted = false; } } @@ -2187,10 +2197,7 @@ int32 MTProtoConnectionPrivate::handleOneReceived(const mtpPrime *from, const mt DEBUG_LOG(("Message Info: msgs_state_req received, ids: %1").arg(logVectorLong(ids))); if (!idsCount) return 1; - MTPMsgsStateInfo req(MTP_msgs_state_info(MTP_long(msgId), MTPstring())); - string &info(req._msgs_state_info().vinfo._string().v); - info.resize(idsCount); - + QByteArray info(idsCount, Qt::Uninitialized); { QReadLocker lock(sessionData->receivedIdsMutex()); const mtpMsgIdsMap &receivedIds(sessionData->receivedIdsSet()); @@ -2227,8 +2234,7 @@ int32 MTProtoConnectionPrivate::handleOneReceived(const mtpPrime *from, const mt info[i] = state; } } - - sessionData->owner()->send(req); + emit sendMsgsStateInfoAsync(msgId, info); } return 1; case mtpc_msgs_state_info: { @@ -2366,9 +2372,11 @@ int32 MTProtoConnectionPrivate::handleOneReceived(const mtpPrime *from, const mt DEBUG_LOG(("Message Info: resend of msgs requested, ids: %1").arg(logVectorLong(ids))); if (!idsCount) return (badTime ? 0 : 1); - for (QVector::const_iterator i = ids.cbegin(), e = ids.cend(); i != e; ++i) { - resend(i->v, 0, false, true); + QVector toResend(ids.size(), Qt::Uninitialized); + for (int32 i = 0, l = ids.size(); i < l; ++i) { + toResend[i] = ids.at(i).v; } + resendMany(toResend, 0, false, true); } return 1; case mtpc_rpc_result: { @@ -2425,7 +2433,7 @@ int32 MTProtoConnectionPrivate::handleOneReceived(const mtpPrime *from, const mt sessionData->setSalt(data.vserver_salt.v); mtpMsgId firstMsgId = data.vfirst_msg_id.v; - QVector toResend; + QVector toResend; { QReadLocker locker(sessionData->haveSentMutex()); const mtpRequestMap &haveSent(sessionData->haveSentMap()); @@ -2435,9 +2443,7 @@ int32 MTProtoConnectionPrivate::handleOneReceived(const mtpPrime *from, const mt if (i.value()->requestId) toResend.push_back(i.key()); } } - for (uint32 i = 0, l = toResend.size(); i < l; ++i) { - resend(toResend[i], 10, true); - } + resendMany(toResend, 10, true); mtpBuffer update(end - from); if (end > from) memcpy(update.data(), from, (end - from) * sizeof(mtpPrime)); @@ -2454,7 +2460,7 @@ int32 MTProtoConnectionPrivate::handleOneReceived(const mtpPrime *from, const mt MTPPing msg(from, end); DEBUG_LOG(("Message Info: ping received, ping_id: %1, sending pong..").arg(msg.vping_id.v)); - sessionData->owner()->send(MTP_pong(MTP_long(msgId), msg.vping_id)); + emit sendPongAsync(msgId, msg.vping_id.v); } return 1; case mtpc_pong: { @@ -2714,9 +2720,19 @@ void MTProtoConnectionPrivate::handleMsgsStates(const QVector &ids, con } } -mtpRequestId MTProtoConnectionPrivate::resend(mtpMsgId msgId, uint64 msCanWait, bool forceContainer, bool sendMsgStateInfo) { - if (msgId == pingMsgId) return 0xFFFFFFFF; - return sessionData->owner()->resend(msgId, msCanWait, forceContainer, sendMsgStateInfo); +void MTProtoConnectionPrivate::resend(quint64 msgId, quint64 msCanWait, bool forceContainer, bool sendMsgStateInfo) { + if (msgId == pingMsgId) return; + emit resendAsync(msgId, msCanWait, forceContainer, sendMsgStateInfo); +} + +void MTProtoConnectionPrivate::resendMany(QVector msgIds, quint64 msCanWait, bool forceContainer, bool sendMsgStateInfo) { + for (int32 i = 0, l = msgIds.size(); i < l; ++i) { + if (msgIds.at(i) == pingMsgId) { + msgIds.remove(i); + --l; + } + } + emit resendManyAsync(msgIds, msCanWait, forceContainer, sendMsgStateInfo); } void MTProtoConnectionPrivate::onConnected() { @@ -3186,7 +3202,7 @@ void MTProtoConnectionPrivate::authKeyCreated() { if (sessionData->getSalt()) { // else receive salt in bad_server_salt first, then try to send all the requests setState(MTProtoConnection::Connected); if (restarted) { - sessionData->owner()->resendAll(); + emit resendAllAsync(); restarted = false; } } @@ -3194,10 +3210,6 @@ void MTProtoConnectionPrivate::authKeyCreated() { toSendPingId = MTP::nonce(); // get server_salt emit needToSendAsync(); - -// disconnect(&pinger, SIGNAL(timeout()), 0, 0); -// connect(&pinger, SIGNAL(timeout()), this, SLOT(sendPing())); -// pinger.start(30000); } void MTProtoConnectionPrivate::clearAuthKeyData() { @@ -3218,10 +3230,6 @@ void MTProtoConnectionPrivate::clearAuthKeyData() { } } -void MTProtoConnectionPrivate::sendPing() { - sessionData->owner()->send(MTPPing(MTP::nonce())); -} - void MTProtoConnectionPrivate::onError(bool mayBeBadKey) { MTP_LOG(dc, ("Restarting after error, maybe bad key: %1..").arg(logBool(mayBeBadKey))); return restart(mayBeBadKey); diff --git a/Telegram/SourceFiles/mtproto/mtpConnection.h b/Telegram/SourceFiles/mtproto/mtpConnection.h index 1dd9be144..7fdad7f53 100644 --- a/Telegram/SourceFiles/mtproto/mtpConnection.h +++ b/Telegram/SourceFiles/mtproto/mtpConnection.h @@ -308,10 +308,15 @@ signals: void needToRestart(); void stateChanged(qint32 newState); void sessionResetDone(); - void needToSendAsync(); - void sendAnythingAsync(quint64); - void sendHttpWait(); + void needToSendAsync(); + void sendAnythingAsync(quint64 msWait); + void sendHttpWaitAsync(); + void sendPongAsync(quint64 msgId, quint64 pingId); + void sendMsgsStateInfoAsync(quint64 msgId, QByteArray data); + void resendAsync(quint64 msgId, quint64 msCanWait, bool forceContainer, bool sendMsgStateInfo); + void resendManyAsync(QVector msgIds, quint64 msCanWait, bool forceContainer, bool sendMsgStateInfo); + void resendAllAsync(); public slots: @@ -344,8 +349,6 @@ public slots: bool updateAuthKey(); - void sendPing(); - void onConfigLoaded(); private: @@ -398,7 +401,8 @@ private: mtpPingId pingId, toSendPingId; mtpMsgId pingMsgId; - mtpRequestId resend(mtpMsgId msgId, uint64 msCanWait = 0, bool forceContainer = false, bool sendMsgStateInfo = false); + void resend(quint64 msgId, quint64 msCanWait = 0, bool forceContainer = false, bool sendMsgStateInfo = false); + void resendMany(QVector msgIds, quint64 msCanWait = 0, bool forceContainer = false, bool sendMsgStateInfo = false); template void sendRequestNotSecure(const TRequest &request); @@ -457,6 +461,4 @@ private: void authKeyCreated(); void clearAuthKeyData(); - QTimer pinger; - }; diff --git a/Telegram/SourceFiles/mtproto/mtpSession.cpp b/Telegram/SourceFiles/mtproto/mtpSession.cpp index 0c7c955de..349408e10 100644 --- a/Telegram/SourceFiles/mtproto/mtpSession.cpp +++ b/Telegram/SourceFiles/mtproto/mtpSession.cpp @@ -113,8 +113,8 @@ void MTProtoSession::start(int32 dcenter, uint32 connects) { if (lock && dc->connectionInited()) { data.setLayerWasInited(true); } - connect(dc.data(), SIGNAL(authKeyCreated()), this, SLOT(authKeyCreatedForDC())); - connect(dc.data(), SIGNAL(layerWasInited(bool)), this, SLOT(layerWasInitedForDC(bool))); + connect(dc.data(), SIGNAL(authKeyCreated()), this, SLOT(authKeyCreatedForDC()), Qt::QueuedConnection); + connect(dc.data(), SIGNAL(layerWasInited(bool)), this, SLOT(layerWasInitedForDC(bool)), Qt::QueuedConnection); } } } @@ -160,6 +160,20 @@ void MTProtoSession::sendHttpWait() { send(MTPHttpWait(MTP_http_wait(MTP_int(100), MTP_int(30), MTP_int(25000))), RPCResponseHandler(), 50); } +void MTProtoSession::sendPong(quint64 msgId, quint64 pingId) { + send(MTP_pong(MTP_long(msgId), MTP_long(pingId))); +} + +void MTProtoSession::sendMsgsStateInfo(quint64 msgId, QByteArray data) { + MTPMsgsStateInfo req(MTP_msgs_state_info(MTP_long(msgId), MTPstring())); + string &info(req._msgs_state_info().vinfo._string().v); + info.resize(data.size()); + if (!data.isEmpty()) { + memcpy(&info[0], data.constData(), data.size()); + } + send(req); +} + void MTProtoSession::checkRequestsByTimer() { QVector resendingIds; QVector removingIds; // remove very old (10 minutes) containers and resend requests @@ -308,7 +322,7 @@ QString MTProtoSession::transport() const { return QString(); } -mtpRequestId MTProtoSession::resend(mtpMsgId msgId, uint64 msCanWait, bool forceContainer, bool sendMsgStateInfo) { +mtpRequestId MTProtoSession::resend(quint64 msgId, quint64 msCanWait, bool forceContainer, bool sendMsgStateInfo) { mtpRequest request; { QWriteLocker locker(data.haveSentMutex()); @@ -348,6 +362,12 @@ mtpRequestId MTProtoSession::resend(mtpMsgId msgId, uint64 msCanWait, bool force } } +void MTProtoSession::resendMany(QVector msgIds, quint64 msCanWait, bool forceContainer, bool sendMsgStateInfo) { + for (int32 i = 0, l = msgIds.size(); i < l; ++i) { + resend(msgIds.at(i), msCanWait, forceContainer, sendMsgStateInfo); + } +} + void MTProtoSession::resendAll() { QVector toResend; { @@ -427,6 +447,7 @@ int32 MTProtoSession::getDC() const { } void MTProtoSession::tryToReceive() { + int32 cnt = 0; while (true) { mtpRequestId requestId; mtpResponse response; @@ -445,6 +466,7 @@ void MTProtoSession::tryToReceive() { } else { _mtp_internal::execCallback(requestId, response.constData(), response.constData() + response.size()); } + ++cnt; } } diff --git a/Telegram/SourceFiles/mtproto/mtpSession.h b/Telegram/SourceFiles/mtproto/mtpSession.h index 04281e839..1f51a6457 100644 --- a/Telegram/SourceFiles/mtproto/mtpSession.h +++ b/Telegram/SourceFiles/mtproto/mtpSession.h @@ -241,9 +241,6 @@ public: int32 getState() const; QString transport() const; - mtpRequestId resend(mtpMsgId msgId, uint64 msCanWait = 0, bool forceContainer = false, bool sendMsgStateInfo = false); - void resendAll(); // after connection restart - void sendPrepared(const mtpRequest &request, uint64 msCanWait = 0, bool newRequest = true); // nulls msgId and seqNo in request, if newRequest = true void sendPreparedWithInit(const mtpRequest &request, uint64 msCanWait = 0); @@ -255,6 +252,10 @@ signals: public slots: + mtpRequestId resend(quint64 msgId, quint64 msCanWait = 0, bool forceContainer = false, bool sendMsgStateInfo = false); + void resendMany(QVector msgIds, quint64 msCanWait, bool forceContainer, bool sendMsgStateInfo); + void resendAll(); // after connection restart + void authKeyCreatedForDC(); void layerWasInitedForDC(bool wasInited); @@ -264,8 +265,9 @@ public slots: void onResetDone(); void sendAnything(quint64 msCanWait); - void sendHttpWait(); + void sendPong(quint64 msgId, quint64 pingId); + void sendMsgsStateInfo(quint64 msgId, QByteArray data); private: diff --git a/Telegram/SourceFiles/settings.cpp b/Telegram/SourceFiles/settings.cpp index d1aa445be..56e195702 100644 --- a/Telegram/SourceFiles/settings.cpp +++ b/Telegram/SourceFiles/settings.cpp @@ -96,6 +96,8 @@ QUrl gUpdateURL = QUrl(qsl("http://tdesktop.com/linux/tupdates/current")); #error Unknown platform #endif +bool gContactsReceived = false; + void settingsParseArgs(int argc, char *argv[]) { if (cPlatform() == dbipMac) { gCustomNotifies = false; diff --git a/Telegram/SourceFiles/settings.h b/Telegram/SourceFiles/settings.h index f57c9fbe2..160f53731 100644 --- a/Telegram/SourceFiles/settings.h +++ b/Telegram/SourceFiles/settings.h @@ -156,4 +156,6 @@ DeclareReadSetting(uint64, Instance); DeclareReadSetting(DBIPlatform, Platform); DeclareReadSetting(QUrl, UpdateURL); +DeclareSetting(bool, ContactsReceived); + void settingsParseArgs(int argc, char *argv[]); diff --git a/Telegram/SourceFiles/window.cpp b/Telegram/SourceFiles/window.cpp index c57d0ba6c..d748ed48b 100644 --- a/Telegram/SourceFiles/window.cpp +++ b/Telegram/SourceFiles/window.cpp @@ -434,6 +434,7 @@ void Window::clearWidgets() { } void Window::setupIntro(bool anim) { + cSetContactsReceived(false); if (intro && (intro->animating() || intro->isVisible()) && !main) return; QPixmap bg = myGrab(this, QRect(0, st::titleHeight, width(), height() - st::titleHeight)); @@ -636,6 +637,13 @@ void Window::hideLayer() { } } +bool Window::hideInnerLayer() { + if (layerBG) { + return layerBG->onInnerClose(); + } + return true; +} + bool Window::layerShown() { return !!layerBG || !!_topWidget; } @@ -810,6 +818,12 @@ void Window::updateTrayMenu(bool force) { #endif } +void Window::onShowAddContact() { + if (isHidden()) showFromTray(); + + if (main) main->showAddContact(); +} + void Window::onShowNewGroup() { if (isHidden()) showFromTray(); diff --git a/Telegram/SourceFiles/window.h b/Telegram/SourceFiles/window.h index 93fedf675..d48feecb5 100644 --- a/Telegram/SourceFiles/window.h +++ b/Telegram/SourceFiles/window.h @@ -172,6 +172,7 @@ public: void showLayer(LayeredWidget *w); void replaceLayer(LayeredWidget *w); void hideLayer(); + bool hideInnerLayer(); bool layerShown(); @@ -240,6 +241,7 @@ public slots: void notifyFire(); void updateTrayMenu(bool force = false); + void onShowAddContact(); void onShowNewGroup(); void onLogout(); void onLogoutSure(); diff --git a/Telegram/Telegram.vcxproj b/Telegram/Telegram.vcxproj index bfef80edf..86c61ca87 100644 --- a/Telegram/Telegram.vcxproj +++ b/Telegram/Telegram.vcxproj @@ -1742,7 +1742,6 @@ - diff --git a/Telegram/Telegram.vcxproj.filters b/Telegram/Telegram.vcxproj.filters index 351fbdb4f..27bef0c35 100644 --- a/Telegram/Telegram.vcxproj.filters +++ b/Telegram/Telegram.vcxproj.filters @@ -1023,7 +1023,6 @@ -