diff --git a/Telegram/Resources/lang.strings b/Telegram/Resources/lang.strings index 058d2fff3..a56ffb0fa 100644 --- a/Telegram/Resources/lang.strings +++ b/Telegram/Resources/lang.strings @@ -583,8 +583,10 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org "lng_stickers_default_set" = "Great Minds"; "lng_stickers_you_have" = "Manage and reorder sticker packs"; "lng_stickers_packs" = "Sticker Packs"; -"lng_stickers_remove" = "Remove"; -"lng_stickers_return" = "Return"; +"lng_stickers_reorder" = "Click and drag to reorder sticker packs"; +"lng_stickers_remove" = "Delete"; +"lng_stickers_return" = "Undo"; +"lng_stickers_restore" = "Restore"; "lng_stickers_count" = "{count:Loading..|# sticker|# stickers}"; "lng_in_dlg_photo" = "Photo"; diff --git a/Telegram/Resources/style.txt b/Telegram/Resources/style.txt index 811308898..bc3a44720 100644 --- a/Telegram/Resources/style.txt +++ b/Telegram/Resources/style.txt @@ -1424,12 +1424,13 @@ contactsNewItemIconPosition: point(29px, 19px); contactsNewItemTop: 18px; contactsNewItemFg: #4b82af; contactsAboutBg: #f7f7f7; +contactsAboutShadow: #0000001F; contactsAdminCheckbox: Checkbox(defaultCheckbox) { font: semiboldFont; textBg: #f7f7f7; textPosition: point(34px, 1px); } -contactsAboutHeight: 80px; +contactsAboutHeight: 42px; contactsAboutTop: 9px; contactsScroll: flatScroll(boxScroll) { deltab: 0px; @@ -1794,6 +1795,8 @@ stickersScroll: flatScroll(boxScroll) { deltat: 23px; deltab: 9px; } +stickersReorderPadding: margins(0px, 12px, 0px, 12px); +stickersReorderFg: #777; stickersRowDisabledOpacity: 0.4; stickersRowDuration: 200; @@ -1938,11 +1941,11 @@ 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); +verifiedCheckProfile: sprite(285px, 235px, 18px, 18px); +verifiedCheckProfilePos: point(7px, 6px); +verifiedCheck: sprite(285px, 221px, 14px, 14px); +verifiedCheckInv: sprite(299px, 221px, 14px, 14px); +verifiedCheckPos: point(4px, 2px); botKbDuration: 200; botKbBg: #f7f7f7; diff --git a/Telegram/SourceFiles/art/sprite.png b/Telegram/SourceFiles/art/sprite.png index 29c40d452..b40fa3297 100644 Binary files a/Telegram/SourceFiles/art/sprite.png and b/Telegram/SourceFiles/art/sprite.png differ diff --git a/Telegram/SourceFiles/art/sprite_200x.png b/Telegram/SourceFiles/art/sprite_200x.png index 54a166f61..05d810234 100644 Binary files a/Telegram/SourceFiles/art/sprite_200x.png and b/Telegram/SourceFiles/art/sprite_200x.png differ diff --git a/Telegram/SourceFiles/boxes/contactsbox.cpp b/Telegram/SourceFiles/boxes/contactsbox.cpp index 8039c4784..3c6c7b18d 100644 --- a/Telegram/SourceFiles/boxes/contactsbox.cpp +++ b/Telegram/SourceFiles/boxes/contactsbox.cpp @@ -94,7 +94,7 @@ namespace { ContactsInner::ContactsInner(ChatData *chat, MembersFilter membersFilter) : TWidget() , _rowHeight(st::contactsPadding.top() + st::contactsPhotoSize + st::contactsPadding.bottom()) -, _newItemHeight((membersFilter == MembersFilterAdmins) ? (st::contactsNewItemHeight + st::contactsAboutHeight) : 0) +, _newItemHeight(0) , _newItemSel(false) , _chat(chat) , _channel(0) @@ -119,8 +119,11 @@ ContactsInner::ContactsInner(ChatData *chat, MembersFilter membersFilter) : TWid , _addContactLnk(this, lang(lng_add_contact_button)) , _saving(false) { initList(); - if (membersFilter == MembersFilterAdmins && !_contacts->list.count) { - App::api()->requestFullPeer(_chat); + if (membersFilter == MembersFilterAdmins) { + _newItemHeight = st::contactsNewItemHeight + qMax(_aboutAllAdmins.countHeight(_aboutWidth), _aboutAdmins.countHeight(_aboutWidth)) + st::contactsAboutHeight; + if (!_contacts->list.count) { + App::api()->requestFullPeer(_chat); + } } init(); } @@ -775,9 +778,9 @@ void ContactsInner::changeCheckState(ContactData *data, PeerData *peer) { int32 ContactsInner::selectedCount() const { int32 result = _selCount; if (_chat) { - result += (_chat->count > 0) ? _chat->count : 1; + result += qMax(_chat->count, 1); } else if (_channel) { - result += _already.size(); + result += qMax(_channel->count, _already.size()); } else if (_creating == CreatingGroupGroup) { result += 1; } diff --git a/Telegram/SourceFiles/boxes/stickersetbox.cpp b/Telegram/SourceFiles/boxes/stickersetbox.cpp index b71970649..cfa0790d3 100644 --- a/Telegram/SourceFiles/boxes/stickersetbox.cpp +++ b/Telegram/SourceFiles/boxes/stickersetbox.cpp @@ -334,11 +334,13 @@ StickersInner::StickersInner() : TWidget() , _aboveShadowFadeStart(0) , _aboveShadowFadeOpacity(0, 0) , _a_shifting(animFunc(this, &StickersInner::animStep_shifting)) +, _itemsTop(st::membersPadding.top()) , _saving(false) , _removeSel(-1) , _removeDown(-1) , _removeWidth(st::normalFont->width(lang(lng_stickers_remove))) , _returnWidth(st::normalFont->width(lang(lng_stickers_return))) +, _restoreWidth(st::normalFont->width(lang(lng_stickers_restore))) , _selected(-1) , _started(-1) , _dragging(-1) @@ -357,14 +359,14 @@ void StickersInner::paintEvent(QPaintEvent *e) { p.fillRect(r, st::white); p.setClipRect(r); - - int32 yFrom = r.y() - st::membersPadding.top(), yTo = r.y() + r.height() - st::membersPadding.top(); - 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 { + p.translate(0, _itemsTop); + + int32 yFrom = r.y() - _itemsTop, yTo = r.y() + r.height() - _itemsTop; int32 from = floorclamp(yFrom - _rowHeight, _rowHeight, 0, _rows.size()); int32 to = ceilclamp(yTo + _rowHeight, _rowHeight, 0, _rows.size()); p.translate(0, from * _rowHeight); @@ -396,7 +398,9 @@ void StickersInner::paintRow(Painter &p, int32 index) { } else { p.setPen(st::btnDefLink.color->p); } - p.drawTextRight(st::contactsPadding.right() + st::contactsCheckPosition.x(), st::contactsPadding.top() + (st::contactsPhotoSize - st::normalFont->height) / 2, width(), lang(s->disabled ? lng_stickers_return : lng_stickers_remove), s->disabled ? _returnWidth : _removeWidth); + int32 remWidth = s->disabled ? (s->official ? _restoreWidth : _returnWidth) : _removeWidth; + QString remText = lang(s->disabled ? (s->official ? lng_stickers_restore : lng_stickers_return) : lng_stickers_remove); + p.drawTextRight(st::contactsPadding.right() + st::contactsCheckPosition.x(), st::contactsPadding.top() + (st::contactsPhotoSize - st::normalFont->height) / 2, width(), remText, remWidth); if (index == _above) { float64 current = _aboveShadowFadeOpacity.current(); @@ -441,7 +445,7 @@ void StickersInner::mousePressEvent(QMouseEvent *e) { onUpdateSelected(); if (_removeSel >= 0) { _removeDown = _removeSel; - update(0, st::membersPadding.top() + _removeSel * _rowHeight, width(), _rowHeight); + update(0, _itemsTop + _removeSel * _rowHeight, width(), _rowHeight); } else if (_selected >= 0) { _above = _dragging = _started = _selected; _dragStart = mapFromGlobal(_mouse); @@ -489,14 +493,14 @@ void StickersInner::onUpdateSelected() { emit checkDraggingScroll(local.y()); } else { - bool in = rect().marginsRemoved(QMargins(0, st::membersPadding.top(), 0, st::membersPadding.bottom())).contains(local); - _selected = in ? floorclamp(local.y() - st::membersPadding.top(), _rowHeight, 0, _rows.size() - 1) : -1; + bool in = rect().marginsRemoved(QMargins(0, _itemsTop, 0, st::membersPadding.bottom())).contains(local); + _selected = in ? floorclamp(local.y() - _itemsTop, _rowHeight, 0, _rows.size() - 1) : -1; int32 removeSel = -1; if (_selected >= 0) { - int32 remw = _rows.at(_selected)->disabled ? _returnWidth : _removeWidth; + int32 remw = _rows.at(_selected)->disabled ? (_rows.at(_selected)->official ? _restoreWidth : _returnWidth) : _removeWidth; QRect rem(myrtlrect(width() - st::contactsPadding.right() - st::contactsCheckPosition.x() - remw, st::contactsPadding.top() + (st::contactsPhotoSize - st::normalFont->height) / 2, remw, st::normalFont->height)); - removeSel = rem.contains(local.x(), local.y() - st::membersPadding.top() - _selected * _rowHeight) ? _selected : -1; + removeSel = rem.contains(local.x(), local.y() - _itemsTop - _selected * _rowHeight) ? _selected : -1; } setRemoveSel(removeSel); emit noDraggingScroll(); @@ -529,7 +533,7 @@ void StickersInner::mouseReleaseEvent(QMouseEvent *e) { _dragging = _started = -1; } if (_removeDown >= 0) { - update(0, st::membersPadding.top() + _removeDown * _rowHeight, width(), _rowHeight); + update(0, _itemsTop + _removeDown * _rowHeight, width(), _rowHeight); _removeDown = -1; } } @@ -551,7 +555,7 @@ void StickersInner::updateAnimatedRegions() { if (updateMax < _dragging) updateMax = _dragging; } if (updateMin >= 0) { - update(0, st::membersPadding.top() + _rowHeight * (updateMin - 1), width(), _rowHeight * (updateMax - updateMin + 3)); + update(0, _itemsTop + _rowHeight * (updateMin - 1), width(), _rowHeight * (updateMax - updateMin + 3)); } } @@ -610,9 +614,9 @@ void StickersInner::clear() { void StickersInner::setRemoveSel(int32 removeSel) { if (removeSel != _removeSel) { - if (_removeSel >= 0) update(0, st::membersPadding.top() + _removeSel * _rowHeight, width(), _rowHeight); + if (_removeSel >= 0) update(0, _itemsTop + _removeSel * _rowHeight, width(), _rowHeight); _removeSel = removeSel; - if (_removeSel >= 0) update(0, st::membersPadding.top() + _removeSel * _rowHeight, width(), _rowHeight); + if (_removeSel >= 0) update(0, _itemsTop + _removeSel * _rowHeight, width(), _rowHeight); setCursor((_removeSel >= 0 && (_removeDown < 0 || _removeDown == _removeSel)) ? style::cur_pointer : style::cur_default); } } @@ -621,7 +625,7 @@ void StickersInner::rebuild() { QList rows, rowsDisabled; int32 namex = st::contactsPadding.left() + st::contactsPhotoSize + st::contactsPadding.left(); - int32 namew = st::boxWideWidth - namex - st::contactsPadding.right() - st::contactsCheckPosition.x() - qMax(_returnWidth, _removeWidth); + int32 namew = st::boxWideWidth - namex - st::contactsPadding.right() - st::contactsCheckPosition.x() - qMax(qMax(_returnWidth, _removeWidth), _restoreWidth); clear(); const StickerSetsOrder &order(cStickerSetsOrder()); @@ -656,7 +660,8 @@ void StickersInner::rebuild() { if (titleWidth > namew) { title = st::contactsNameFont->elided(title, namew); } - (disabled ? rowsDisabled : rows).push_back(new StickerSetRow(it->id, sticker, it->stickers.size(), title, disabled, pixw, pixh)); + bool official = (it->flags & MTPDstickerSet::flag_official); + (disabled ? rowsDisabled : rows).push_back(new StickerSetRow(it->id, sticker, it->stickers.size(), title, official, disabled, pixw, pixh)); _animStartTimes.push_back(0); if (it->stickers.isEmpty() || (it->flags & MTPDstickerSet_flag_NOT_LOADED)) { App::api()->scheduleStickerSetRequest(it->id, it->access); @@ -665,7 +670,7 @@ void StickersInner::rebuild() { } App::api()->requestStickerSets(); _rows = rows + rowsDisabled; - resize(width(), st::membersPadding.top() + _rows.size() * _rowHeight + st::membersPadding.bottom()); + resize(width(), _itemsTop + _rows.size() * _rowHeight + st::membersPadding.bottom()); } QVector StickersInner::getOrder() const { @@ -706,8 +711,13 @@ StickersBox::StickersBox() : ItemListBox(st::boxScroll) , _save(this, lang(lng_settings_save), st::defaultBoxButton) , _cancel(this, lang(lng_cancel), st::cancelBoxButton) , _reorderRequest(0) -, _bottomShadow(this) { - ItemListBox::init(&_inner, st::boxButtonPadding.top() + _save.height() + st::boxButtonPadding.bottom()); +, _topShadow(this, st::contactsAboutShadow) +, _bottomShadow(this) +, _scrollDelta(0) +, _aboutWidth(st::boxWideWidth - st::contactsPadding.left() - st::contactsPhotoSize - st::contactsPadding.left() - st::contactsPadding.right()) +, _about(st::boxTextFont, lang(lng_stickers_reorder), _defaultOptions, _aboutWidth) +, _aboutHeight(st::stickersReorderPadding.top() + _about.countHeight(_aboutWidth) + st::stickersReorderPadding.bottom()) { + ItemListBox::init(&_inner, st::boxButtonPadding.top() + _save.height() + st::boxButtonPadding.bottom(), st::boxTitleHeight + _aboutHeight); setMaxHeight(snap(countHeight(), int32(st::sessionsHeight), int32(st::boxMaxListHeight))); connect(App::main(), SIGNAL(stickersUpdated()), this, SLOT(onStickersUpdated())); @@ -727,7 +737,7 @@ StickersBox::StickersBox() : ItemListBox(st::boxScroll) } int32 StickersBox::countHeight() const { - return st::boxTitleHeight + _inner.height() + st::boxButtonPadding.top() + _save.height() + st::boxButtonPadding.bottom(); + return st::boxTitleHeight + _aboutHeight + _inner.height() + st::boxButtonPadding.top() + _save.height() + st::boxButtonPadding.bottom(); } void StickersBox::disenableDone(const MTPBool & result, mtpRequestId req) { @@ -780,6 +790,10 @@ void StickersBox::paintEvent(QPaintEvent *e) { paintTitle(p, lang(lng_stickers_packs)); p.translate(0, st::boxTitleHeight); + + p.fillRect(0, 0, width(), _aboutHeight, st::contactsAboutBg); + p.setPen(st::stickersReorderFg); + _about.drawLeft(p, st::contactsPadding.left() + st::contactsPhotoSize + st::contactsPadding.left(), st::stickersReorderPadding.top(), _aboutWidth, width()); } void StickersBox::closePressed() { @@ -803,6 +817,7 @@ void StickersBox::resizeEvent(QResizeEvent *e) { _save.moveToRight(st::boxButtonPadding.right(), height() - st::boxButtonPadding.bottom() - _save.height()); _cancel.moveToRight(st::boxButtonPadding.right() + _save.width() + st::boxButtonPadding.left(), _save.y()); _inner.resize(width(), _inner.height()); + _topShadow.setGeometry(0, st::boxTitleHeight + _aboutHeight, width(), st::lineWidth); _bottomShadow.setGeometry(0, height() - st::boxButtonPadding.bottom() - _save.height() - st::boxButtonPadding.top() - st::lineWidth, width(), st::lineWidth); _inner.setVisibleScrollbar((_scroll.scrollTopMax() > 0) ? (st::boxScroll.width - st::boxScroll.deltax) : 0); } @@ -908,6 +923,7 @@ void StickersBox::onSave() { void StickersBox::hideAll() { _save.hide(); _cancel.hide(); + _topShadow.hide(); _bottomShadow.hide(); ItemListBox::hideAll(); } @@ -915,6 +931,7 @@ void StickersBox::hideAll() { void StickersBox::showAll() { _save.show(); _cancel.show(); + _topShadow.show(); _bottomShadow.show(); ItemListBox::showAll(); } diff --git a/Telegram/SourceFiles/boxes/stickersetbox.h b/Telegram/SourceFiles/boxes/stickersetbox.h index 3b8b239c1..b896c8af4 100644 --- a/Telegram/SourceFiles/boxes/stickersetbox.h +++ b/Telegram/SourceFiles/boxes/stickersetbox.h @@ -154,10 +154,11 @@ private: int32 _rowHeight; struct StickerSetRow { - StickerSetRow(uint64 id, DocumentData *sticker, int32 count, const QString &title, bool disabled, int32 pixw, int32 pixh) : id(id) + StickerSetRow(uint64 id, DocumentData *sticker, int32 count, const QString &title, bool official, bool disabled, int32 pixw, int32 pixh) : id(id) , sticker(sticker) , count(count) , title(title) + , official(official) , disabled(disabled) , pixw(pixw) , pixh(pixh) @@ -167,7 +168,7 @@ private: DocumentData *sticker; int32 count; QString title; - bool disabled; + bool official, disabled; int32 pixw, pixh; anim::ivalue yadd; }; @@ -178,9 +179,11 @@ private: anim::fvalue _aboveShadowFadeOpacity; Animation _a_shifting; + int32 _itemsTop; + bool _saving; - int32 _removeSel, _removeDown, _removeWidth, _returnWidth; + int32 _removeSel, _removeDown, _removeWidth, _returnWidth, _restoreWidth; QPoint _mouse; int32 _selected; @@ -232,11 +235,16 @@ private: BoxButton _save, _cancel; QMap _disenableRequests; mtpRequestId _reorderRequest; + PlainShadow _topShadow; ScrollableBoxShadow _bottomShadow; QTimer _scrollTimer; int32 _scrollDelta; + int32 _aboutWidth; + Text _about; + int32 _aboutHeight; + }; int32 stickerPacksCount(bool includeDisabledOfficial = false); diff --git a/Telegram/SourceFiles/config.h b/Telegram/SourceFiles/config.h index 992b92152..c36eede31 100644 --- a/Telegram/SourceFiles/config.h +++ b/Telegram/SourceFiles/config.h @@ -59,6 +59,8 @@ enum { MTPDebugBufferSize = 1024 * 1024, // 1 mb start size + MaxUsersPerInvite = 100, // max users in one super group invite request + MTPPingDelayDisconnect = 60, // 1 min MTPPingSendAfterAuto = 30, // send new ping starting from 30 seconds (add to existing container) MTPPingSendAfter = 45, // send new ping after 45 seconds without ping diff --git a/Telegram/SourceFiles/dialogswidget.cpp b/Telegram/SourceFiles/dialogswidget.cpp index bf7d794a7..56d96241d 100644 --- a/Telegram/SourceFiles/dialogswidget.cpp +++ b/Telegram/SourceFiles/dialogswidget.cpp @@ -56,6 +56,7 @@ DialogsInner::DialogsInner(QWidget *parent, MainWidget *main) : SplittedWidget(p , _searchInPeer(0) , _searchInMigrated(0) , _menuPeer(0) +, _menuActionPeer(0) , _menu(0) { connect(App::wnd(), SIGNAL(imageLoaded()), this, SLOT(update())); connect(main, SIGNAL(peerNameChanged(PeerData*, const PeerData::Names&, const PeerData::NameFirstChars&)), this, SLOT(onPeerNameChanged(PeerData*, const PeerData::Names&, const PeerData::NameFirstChars&))); @@ -64,7 +65,7 @@ DialogsInner::DialogsInner(QWidget *parent, MainWidget *main) : SplittedWidget(p connect(&_addContactLnk, SIGNAL(clicked()), App::wnd(), SLOT(onShowAddContact())); connect(&_cancelSearchInPeer, SIGNAL(clicked()), this, SIGNAL(cancelSearchInPeer())); _cancelSearchInPeer.hide(); - refresh(false); + refresh(); } int32 DialogsInner::filteredOffset() const { @@ -608,6 +609,7 @@ void DialogsInner::contextMenuEvent(QContextMenuEvent *e) { _menuPeer = 0; disconnect(App::main(), SIGNAL(peerUpdated(PeerData*)), this, SLOT(peerUpdated(PeerData*))); } + if (e->reason() == QContextMenuEvent::Mouse) { lastMousePos = e->globalPos(); selByMouse = true; @@ -632,8 +634,10 @@ void DialogsInner::contextMenuEvent(QContextMenuEvent *e) { if (_menuPeer->isUser()) { _menu->addAction(lang(lng_profile_clear_history), this, SLOT(onContextClearHistory()))->setEnabled(true); _menu->addAction(lang(lng_profile_delete_conversation), this, SLOT(onContextDeleteAndLeave()))->setEnabled(true); - _menu->addAction(lang((_menuPeer->asUser()->blocked == UserIsBlocked) ? (_menuPeer->asUser()->botInfo ? lng_profile_unblock_bot : lng_profile_unblock_user) : (_menuPeer->asUser()->botInfo ? lng_profile_block_bot : lng_profile_block_user)), this, SLOT(onContextToggleBlock()))->setEnabled(true); - connect(App::main(), SIGNAL(peerUpdated(PeerData*)), this, SLOT(peerUpdated(PeerData*))); + if (_menuPeer->asUser()->access != UserNoAccess) { + _menu->addAction(lang((_menuPeer->asUser()->blocked == UserIsBlocked) ? (_menuPeer->asUser()->botInfo ? lng_profile_unblock_bot : lng_profile_unblock_user) : (_menuPeer->asUser()->botInfo ? lng_profile_block_bot : lng_profile_block_user)), this, SLOT(onContextToggleBlock()))->setEnabled(true); + connect(App::main(), SIGNAL(peerUpdated(PeerData*)), this, SLOT(peerUpdated(PeerData*))); + } } else if (_menuPeer->isChat()) { _menu->addAction(lang(lng_profile_clear_history), this, SLOT(onContextClearHistory()))->setEnabled(true); _menu->addAction(lang(lng_profile_clear_and_exit), this, SLOT(onContextDeleteAndLeave()))->setEnabled(true); @@ -667,39 +671,42 @@ void DialogsInner::onContextSearch() { void DialogsInner::onContextClearHistory() { if (!_menuPeer || _menuPeer->isChannel()) return; + + _menuActionPeer = _menuPeer; ConfirmBox *box = new ConfirmBox(_menuPeer->isUser() ? lng_sure_delete_history(lt_contact, _menuPeer->name) : lng_sure_delete_group_history(lt_group, _menuPeer->name), lang(lng_box_delete), st::attentionBoxButton); connect(box, SIGNAL(confirmed()), this, SLOT(onContextClearHistorySure())); App::showLayer(box); } void DialogsInner::onContextClearHistorySure() { - if (!_menuPeer || _menuPeer->isChannel()) return; + if (!_menuActionPeer || _menuActionPeer->isChannel()) return; App::wnd()->hideLayer(); - App::main()->clearHistory(_menuPeer); + App::main()->clearHistory(_menuActionPeer); } void DialogsInner::onContextDeleteAndLeave() { if (!_menuPeer) return; + + _menuActionPeer = _menuPeer; ConfirmBox *box = new ConfirmBox(_menuPeer->isUser() ? lng_sure_delete_history(lt_contact, _menuPeer->name) : (_menuPeer->isChat() ? lng_sure_delete_and_exit(lt_group, _menuPeer->name) : lang(_menuPeer->isMegagroup() ? lng_sure_leave_group : lng_sure_leave_channel)), lang(_menuPeer->isUser() ? lng_box_delete : lng_box_leave), _menuPeer->isChannel() ? st::defaultBoxButton : st::attentionBoxButton); connect(box, SIGNAL(confirmed()), this, SLOT(onContextDeleteAndLeaveSure())); App::wnd()->showLayer(box); } void DialogsInner::onContextDeleteAndLeaveSure() { - if (!_menuPeer) return; - if (_menuPeer->isUser()) { - App::main()->deleteConversation(_menuPeer); - } else if (_menuPeer->isChat()) { - App::wnd()->hideLayer(); - App::main()->showDialogs(); - MTP::send(MTPmessages_DeleteChatUser(_menuPeer->asChat()->inputChat, App::self()->inputUser), App::main()->rpcDone(&MainWidget::deleteHistoryAfterLeave, _menuPeer), App::main()->rpcFail(&MainWidget::leaveChatFailed, _menuPeer)); - } else if (_menuPeer->isChannel()) { - App::wnd()->hideLayer(); - App::main()->showDialogs(); - if (_menuPeer->migrateFrom()) { - App::main()->deleteConversation(_menuPeer->migrateFrom()); + if (!_menuActionPeer) return; + + App::wnd()->hideLayer(); + App::main()->showDialogs(); + if (_menuActionPeer->isUser()) { + App::main()->deleteConversation(_menuActionPeer); + } else if (_menuActionPeer->isChat()) { + MTP::send(MTPmessages_DeleteChatUser(_menuActionPeer->asChat()->inputChat, App::self()->inputUser), App::main()->rpcDone(&MainWidget::deleteHistoryAfterLeave, _menuActionPeer), App::main()->rpcFail(&MainWidget::leaveChatFailed, _menuActionPeer)); + } else if (_menuActionPeer->isChannel()) { + if (_menuActionPeer->migrateFrom()) { + App::main()->deleteConversation(_menuActionPeer->migrateFrom()); } - MTP::send(MTPchannels_LeaveChannel(_menuPeer->asChannel()->inputChannel), App::main()->rpcDone(&MainWidget::sentUpdatesReceived)); + MTP::send(MTPchannels_LeaveChannel(_menuActionPeer->asChannel()->inputChannel), App::main()->rpcDone(&MainWidget::sentUpdatesReceived)); } } @@ -919,13 +926,13 @@ void DialogsInner::itemReplaced(HistoryItem *oldItem, HistoryItem *newItem) { } void DialogsInner::updateNotifySettings(PeerData *peer) { - if (_menu && _menuPeer == peer) { + if (_menu && _menuPeer == peer && _menu->actions().size() > 1) { _menu->actions().at(1)->setText(lang(menuPeerMuted() ? lng_enable_notifications_from_tray : lng_disable_notifications_from_tray)); } } void DialogsInner::peerUpdated(PeerData *peer) { - if (_menu && _menuPeer == peer && _menuPeer->isUser()) { + if (_menu && _menuPeer == peer && _menuPeer->isUser() && _menu->actions().size() > 5) { _menu->actions().at(5)->setText(lang((_menuPeer->asUser()->blocked == UserIsBlocked) ? (_menuPeer->asUser()->botInfo ? lng_profile_unblock_bot : lng_profile_unblock_user) : (_menuPeer->asUser()->botInfo ? lng_profile_block_bot : lng_profile_block_user))); } } @@ -1175,7 +1182,6 @@ void DialogsInner::setState(State newState) { _filteredSel = -1; } onFilterUpdate(_filter, true); - refresh(true); } DialogsInner::State DialogsInner::state() const { @@ -1848,7 +1854,9 @@ bool DialogsWidget::animStep_show(float64 ms) { _scroll.show(); _filter.show(); - onFilterUpdate(true); + _a_show.stop(); + + onFilterUpdate(); activate(); if (App::app()) App::app()->mtpUnpause(); diff --git a/Telegram/SourceFiles/dialogswidget.h b/Telegram/SourceFiles/dialogswidget.h index eaea775e7..602774d23 100644 --- a/Telegram/SourceFiles/dialogswidget.h +++ b/Telegram/SourceFiles/dialogswidget.h @@ -204,7 +204,7 @@ private: bool _overDelete; - PeerData *_searchInPeer, *_searchInMigrated, *_menuPeer; + PeerData *_searchInPeer, *_searchInMigrated, *_menuPeer, *_menuActionPeer; PopupMenu *_menu; diff --git a/Telegram/SourceFiles/historywidget.cpp b/Telegram/SourceFiles/historywidget.cpp index 9044026ca..a50e56abd 100644 --- a/Telegram/SourceFiles/historywidget.cpp +++ b/Telegram/SourceFiles/historywidget.cpp @@ -4252,7 +4252,7 @@ void HistoryWidget::blockDone(PeerData *peer, const MTPBool &result) { } void HistoryWidget::onBotStart() { - if (!_peer || !_peer->isUser() || !_peer->asUser()->botInfo) { + if (!_peer || !_peer->isUser() || !_peer->asUser()->botInfo || !_canSendMessages) { updateControlsVisibility(); return; } @@ -4819,7 +4819,7 @@ bool HistoryWidget::hasBroadcastToggle() const { } bool HistoryWidget::isBotStart() const { - if (!_peer || !_peer->isUser() || !_peer->asUser()->botInfo) return false; + if (!_peer || !_peer->isUser() || !_peer->asUser()->botInfo || !_canSendMessages) return false; return !_peer->asUser()->botInfo->startToken.isEmpty() || (_history->isEmpty() && !_history->lastMsg); } @@ -5899,7 +5899,7 @@ void HistoryWidget::updateBotKeyboard(History *h) { if (_keyboard.singleUse() && _keyboard.hasMarkup() && _keyboard.forMsgId() == FullMsgId(_channel, _history->lastKeyboardId) && _history->lastKeyboardUsed) { _history->lastKeyboardHiddenId = _history->lastKeyboardId; } - if (!isBotStart() && !isBlocked() && (wasVisible || _replyTo || (!_field.hasSendText() && !kbWasHidden()))) { + if (!isBotStart() && !isBlocked() && _canSendMessages && (wasVisible || _replyTo || (!_field.hasSendText() && !kbWasHidden()))) { if (!_a_show.animating()) { if (hasMarkup) { _kbScroll.show(); diff --git a/Telegram/SourceFiles/localstorage.cpp b/Telegram/SourceFiles/localstorage.cpp index e5e395c19..362798d5e 100644 --- a/Telegram/SourceFiles/localstorage.cpp +++ b/Telegram/SourceFiles/localstorage.cpp @@ -2467,7 +2467,7 @@ namespace Local { TaskId startStickerImageLoad(const StorageKey &location, mtpFileLoader *loader) { StorageMap::iterator j = _stickerImagesMap.find(location); - if (j == _stickerImagesMap.cend()) { + if (j == _stickerImagesMap.cend() || !_localLoader) { return 0; } return _localLoader->addTask(new StickerImageLoadTask(j->first, location, loader)); @@ -2526,7 +2526,7 @@ namespace Local { TaskId startAudioLoad(const StorageKey &location, mtpFileLoader *loader) { StorageMap::iterator j = _audiosMap.find(location); - if (j == _audiosMap.cend()) { + if (j == _audiosMap.cend() || !_localLoader) { return 0; } return _localLoader->addTask(new AudioLoadTask(j->first, location, loader)); diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index f95392a5f..0fa3ed35e 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -971,11 +971,17 @@ void MainWidget::addParticipants(PeerData *chatOrChannel, const QVectorisChannel()) { QVector inputUsers; - inputUsers.reserve(users.size()); + inputUsers.reserve(qMin(users.size(), int(MaxUsersPerInvite))); for (QVector::const_iterator i = users.cbegin(), e = users.cend(); i != e; ++i) { inputUsers.push_back((*i)->inputUser); + if (inputUsers.size() == MaxUsersPerInvite) { + MTP::send(MTPchannels_InviteToChannel(chatOrChannel->asChannel()->inputChannel, MTP_vector(inputUsers)), rpcDone(&MainWidget::inviteToChannelDone, chatOrChannel->asChannel()), rpcFail(&MainWidget::addParticipantsFail, chatOrChannel->asChannel()), 0, 5); + inputUsers.clear(); + } + } + if (!inputUsers.isEmpty()) { + MTP::send(MTPchannels_InviteToChannel(chatOrChannel->asChannel()->inputChannel, MTP_vector(inputUsers)), rpcDone(&MainWidget::inviteToChannelDone, chatOrChannel->asChannel()), rpcFail(&MainWidget::addParticipantsFail, chatOrChannel->asChannel()), 0, 5); } - MTP::send(MTPchannels_InviteToChannel(chatOrChannel->asChannel()->inputChannel, MTP_vector(inputUsers)), rpcDone(&MainWidget::inviteToChannelDone, chatOrChannel->asChannel()), rpcFail(&MainWidget::addParticipantsFail, chatOrChannel->asChannel()), 0, 5); } } diff --git a/Telegram/SourceFiles/profilewidget.cpp b/Telegram/SourceFiles/profilewidget.cpp index 79022abac..6841cde65 100644 --- a/Telegram/SourceFiles/profilewidget.cpp +++ b/Telegram/SourceFiles/profilewidget.cpp @@ -1636,7 +1636,7 @@ void ProfileInner::showAll() { _invitationLink.hide(); } } - if (_peerChannel->count < cMaxMegaGroupCount() && _peerChannel->isMegagroup() && (_amCreator || _peerChannel->amEditor())) { + if (_peerChannel->count < cMaxMegaGroupCount() && _peerChannel->isMegagroup() && (true || _amCreator || _peerChannel->amEditor())) { _addParticipant.show(); } else { _addParticipant.hide(); diff --git a/Telegram/SourceFiles/pspecific_wnd.cpp b/Telegram/SourceFiles/pspecific_wnd.cpp index ee373f103..8bfef9751 100644 --- a/Telegram/SourceFiles/pspecific_wnd.cpp +++ b/Telegram/SourceFiles/pspecific_wnd.cpp @@ -72,7 +72,12 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org #define WM_NCPOINTERUP 0x0243 #endif -const WCHAR AppUserModelId[] = L"Telegram.TelegramDesktop"; +const WCHAR AppUserModelIdRelease[] = L"Telegram.TelegramDesktop"; +const WCHAR AppUserModelIdBeta[] = L"Telegram.TelegramDesktop.Beta"; + +const WCHAR *AppUserModelId() { + return cBetaVersion() ? AppUserModelIdBeta : AppUserModelIdRelease; +} static const PROPERTYKEY pkey_AppUserModel_ID = { { 0x9F4C2855, 0x9F79, 0x4B39, { 0xA8, 0xD0, 0xE1, 0xD4, 0x2D, 0xE1, 0xD5, 0xF3 } }, 5 }; static const PROPERTYKEY pkey_AppUserModel_StartPinOption = { { 0x9F4C2855, 0x9F79, 0x4B39, { 0xA8, 0xD0, 0xE1, 0xD4, 0x2D, 0xE1, 0xD5, 0xF3 } }, 12 }; @@ -2301,7 +2306,7 @@ void _manageAppLnk(bool create, bool silent, int path_csidl, const wchar_t *args hr = shellLink.As(&propertyStore); if (SUCCEEDED(hr)) { PROPVARIANT appIdPropVar; - hr = InitPropVariantFromString(AppUserModelId, &appIdPropVar); + hr = InitPropVariantFromString(AppUserModelId(), &appIdPropVar); if (SUCCEEDED(hr)) { hr = propertyStore->SetValue(pkey_AppUserModel_ID, appIdPropVar); PropVariantClear(&appIdPropVar); @@ -2921,7 +2926,7 @@ void CheckPinnedAppUserModelId() { WCHAR already[MAX_PATH]; hr = propVariantToString(appIdPropVar, already, MAX_PATH); if (SUCCEEDED(hr)) { - if (std::wstring(AppUserModelId) == already) { + if (std::wstring(AppUserModelId()) == already) { LOG(("Already!")); PropVariantClear(&appIdPropVar); return; @@ -2933,7 +2938,7 @@ void CheckPinnedAppUserModelId() { } PropVariantClear(&appIdPropVar); - hr = InitPropVariantFromString(AppUserModelId, &appIdPropVar); + hr = InitPropVariantFromString(AppUserModelId(), &appIdPropVar); if (!SUCCEEDED(hr)) return; hr = propertyStore->SetValue(pkey_AppUserModel_ID, appIdPropVar); @@ -3028,7 +3033,7 @@ bool ValidateAppUserModelIdShortcutAt(const QString &path) { WCHAR already[MAX_PATH]; hr = propVariantToString(appIdPropVar, already, MAX_PATH); if (SUCCEEDED(hr)) { - if (std::wstring(AppUserModelId) == already) { + if (std::wstring(AppUserModelId()) == already) { PropVariantClear(&appIdPropVar); return true; } @@ -3039,7 +3044,7 @@ bool ValidateAppUserModelIdShortcutAt(const QString &path) { } PropVariantClear(&appIdPropVar); - hr = InitPropVariantFromString(AppUserModelId, &appIdPropVar); + hr = InitPropVariantFromString(AppUserModelId(), &appIdPropVar); if (!SUCCEEDED(hr)) return false; hr = propertyStore->SetValue(pkey_AppUserModel_ID, appIdPropVar); @@ -3062,11 +3067,16 @@ bool ValidateAppUserModelIdShortcut() { QString path = systemShortcutPath(); if (path.isEmpty()) return false; - if (ValidateAppUserModelIdShortcutAt(path + qsl("Telegram Desktop/Telegram.lnk"))) return true; - if (ValidateAppUserModelIdShortcutAt(path + qsl("Telegram Win (Unofficial)/Telegram.lnk"))) return true; - - path += qsl("Telegram.lnk"); - if (ValidateAppUserModelIdShortcutAt(path)) return true; + if (cBetaVersion()) { + path += qsl("TelegramBeta.lnk"); + if (ValidateAppUserModelIdShortcutAt(path)) return true; + } else { + if (ValidateAppUserModelIdShortcutAt(path + qsl("Telegram Desktop/Telegram.lnk"))) return true; + if (ValidateAppUserModelIdShortcutAt(path + qsl("Telegram Win (Unofficial)/Telegram.lnk"))) return true; + + path += qsl("Telegram.lnk"); + if (ValidateAppUserModelIdShortcutAt(path)) return true; + } ComPtr shellLink; HRESULT hr = CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&shellLink)); @@ -3086,7 +3096,7 @@ bool ValidateAppUserModelIdShortcut() { if (!SUCCEEDED(hr)) return false; PROPVARIANT appIdPropVar; - hr = InitPropVariantFromString(AppUserModelId, &appIdPropVar); + hr = InitPropVariantFromString(AppUserModelId(), &appIdPropVar); if (!SUCCEEDED(hr)) return false; hr = propertyStore->SetValue(pkey_AppUserModel_ID, appIdPropVar); @@ -3116,13 +3126,13 @@ bool ValidateAppUserModelIdShortcut() { bool InitToastManager() { if (!useToast || !ValidateAppUserModelIdShortcut()) return false; - if (!SUCCEEDED(setCurrentProcessExplicitAppUserModelID(AppUserModelId))) { + if (!SUCCEEDED(setCurrentProcessExplicitAppUserModelID(AppUserModelId()))) { return false; } if (!SUCCEEDED(wrap_GetActivationFactory(StringReferenceWrapper(RuntimeClass_Windows_UI_Notifications_ToastNotificationManager).Get(), &toastNotificationManager))) { return false; } - if (!SUCCEEDED(toastNotificationManager->CreateToastNotifierWithId(StringReferenceWrapper(AppUserModelId).Get(), &toastNotifier))) { + if (!SUCCEEDED(toastNotificationManager->CreateToastNotifierWithId(StringReferenceWrapper(AppUserModelId(), wcslen(AppUserModelId())).Get(), &toastNotifier))) { return false; } if (!SUCCEEDED(wrap_GetActivationFactory(StringReferenceWrapper(RuntimeClass_Windows_UI_Notifications_ToastNotification).Get(), &toastNotificationFactory))) {