New profile fixed top bar now is peer observer.

Multiple showAnimated() calls for SectionWidget are now allowed.
This commit is contained in:
John Preston 2016-05-27 18:45:35 +03:00
parent 2c5c25962c
commit a06a989f97
9 changed files with 112 additions and 26 deletions

View file

@ -381,7 +381,8 @@ namespace {
PeerId peer(peerFromUser(d.vid.v)); PeerId peer(peerFromUser(d.vid.v));
data = App::user(peer); data = App::user(peer);
auto canShareThisContact = data->canShareThisContact(); auto canShareThisContact = data->canShareThisContactFast();
wasContact = data->isContact();
data->input = MTP_inputPeerUser(d.vid, MTP_long(0)); data->input = MTP_inputPeerUser(d.vid, MTP_long(0));
data->inputUser = MTP_inputUser(d.vid, MTP_long(0)); data->inputUser = MTP_inputUser(d.vid, MTP_long(0));
@ -390,13 +391,15 @@ namespace {
data->access = UserNoAccess; data->access = UserNoAccess;
data->flags = 0; data->flags = 0;
data->setBotInfoVersion(-1); data->setBotInfoVersion(-1);
wasContact = (data->contact > 0);
status = &emptyStatus; status = &emptyStatus;
data->contact = -1; data->contact = -1;
if (canShareThisContact != data->canShareThisContact()) { if (canShareThisContact != data->canShareThisContactFast()) {
update.flags |= UpdateFlag::UserCanShareContact; update.flags |= UpdateFlag::UserCanShareContact;
} }
if (wasContact != data->isContact()) {
update.flags |= UpdateFlag::UserIsContact;
}
} break; } break;
case mtpc_user: { case mtpc_user: {
const auto &d(user.c_user()); const auto &d(user.c_user());
@ -404,8 +407,8 @@ namespace {
PeerId peer(peerFromUser(d.vid.v)); PeerId peer(peerFromUser(d.vid.v));
data = App::user(peer); data = App::user(peer);
auto canShareThisContact = data->canShareThisContact(); auto canShareThisContact = data->canShareThisContactFast();
wasContact = data->isContact();
if (!minimal) { if (!minimal) {
data->flags = d.vflags.v; data->flags = d.vflags.v;
if (d.is_self()) { if (d.is_self()) {
@ -468,7 +471,6 @@ namespace {
if (d.has_access_hash()) data->access = d.vaccess_hash.v; if (d.has_access_hash()) data->access = d.vaccess_hash.v;
status = d.has_status() ? &d.vstatus : &emptyStatus; status = d.has_status() ? &d.vstatus : &emptyStatus;
} }
wasContact = (data->contact > 0);
if (!minimal) { if (!minimal) {
if (d.has_bot_info_version()) { if (d.has_bot_info_version()) {
data->setBotInfoVersion(d.vbot_info_version.v); data->setBotInfoVersion(d.vbot_info_version.v);
@ -489,9 +491,12 @@ namespace {
} }
} }
if (canShareThisContact != data->canShareThisContact()) { if (canShareThisContact != data->canShareThisContactFast()) {
update.flags |= UpdateFlag::UserCanShareContact; update.flags |= UpdateFlag::UserCanShareContact;
} }
if (wasContact != data->isContact()) {
update.flags |= UpdateFlag::UserIsContact;
}
} break; } break;
} }
@ -647,6 +652,7 @@ namespace {
auto wasInChannel = cdata->amIn(); auto wasInChannel = cdata->amIn();
auto canEditPhoto = cdata->canEditPhoto(); auto canEditPhoto = cdata->canEditPhoto();
auto canAddMembers = cdata->canAddParticipants(); auto canAddMembers = cdata->canAddParticipants();
auto wasEditor = cdata->amEditor();
if (minimal) { if (minimal) {
MTPDchannel::Flags mask = MTPDchannel::Flag::f_broadcast | MTPDchannel::Flag::f_verified | MTPDchannel::Flag::f_megagroup | MTPDchannel::Flag::f_democracy; MTPDchannel::Flags mask = MTPDchannel::Flag::f_broadcast | MTPDchannel::Flag::f_verified | MTPDchannel::Flag::f_megagroup | MTPDchannel::Flag::f_democracy;
@ -681,6 +687,9 @@ namespace {
if (canAddMembers != cdata->canAddParticipants()) { if (canAddMembers != cdata->canAddParticipants()) {
update.flags |= UpdateFlag::ChannelCanAddMembers; update.flags |= UpdateFlag::ChannelCanAddMembers;
} }
if (wasEditor != cdata->amEditor()) {
update.flags |= UpdateFlag::ChannelAmEditor;
}
} break; } break;
case mtpc_channelForbidden: { case mtpc_channelForbidden: {
auto &d(chat.c_channelForbidden()); auto &d(chat.c_channelForbidden());
@ -693,6 +702,7 @@ namespace {
auto wasInChannel = cdata->amIn(); auto wasInChannel = cdata->amIn();
auto canEditPhoto = cdata->canEditPhoto(); auto canEditPhoto = cdata->canEditPhoto();
auto canAddMembers = cdata->canAddParticipants(); auto canAddMembers = cdata->canAddParticipants();
auto wasEditor = cdata->amEditor();
cdata->inputChannel = MTP_inputChannel(d.vid, d.vaccess_hash); cdata->inputChannel = MTP_inputChannel(d.vid, d.vaccess_hash);
@ -713,6 +723,9 @@ namespace {
if (canAddMembers != cdata->canAddParticipants()) { if (canAddMembers != cdata->canAddParticipants()) {
update.flags |= UpdateFlag::ChannelCanAddMembers; update.flags |= UpdateFlag::ChannelCanAddMembers;
} }
if (wasEditor != cdata->amEditor()) {
update.flags |= UpdateFlag::ChannelAmEditor;
}
} break; } break;
} }
if (!data) continue; if (!data) continue;
@ -1227,7 +1240,7 @@ namespace {
void feedUserLinkDelayed(MTPint userId, const MTPContactLink &myLink, const MTPContactLink &foreignLink) { void feedUserLinkDelayed(MTPint userId, const MTPContactLink &myLink, const MTPContactLink &foreignLink) {
UserData *user = userLoaded(userId.v); UserData *user = userLoaded(userId.v);
if (user) { if (user) {
bool wasContact = (user->contact > 0); auto wasContact = user->isContact();
bool wasShowPhone = !user->contact; bool wasShowPhone = !user->contact;
switch (myLink.type()) { switch (myLink.type()) {
case mtpc_contactLinkContact: case mtpc_contactLinkContact:
@ -1250,6 +1263,12 @@ namespace {
user->contact = 0; user->contact = 0;
} }
} }
if (wasContact != user->isContact()) {
Notify::PeerUpdate update(user);
update.flags |= Notify::PeerUpdateFlag::UserIsContact;
Notify::peerUpdatedDelayed(update);
}
if ((user->contact > 0 && !wasContact) || (wasContact && user->contact < 1)) { if ((user->contact > 0 && !wasContact) || (wasContact && user->contact < 1)) {
Notify::userIsContactChanged(user); Notify::userIsContactChanged(user);
} }
@ -2353,11 +2372,25 @@ namespace {
} }
void regSharedContactItem(int32 userId, HistoryItem *item) { void regSharedContactItem(int32 userId, HistoryItem *item) {
auto user = App::userLoaded(userId);
auto canShareThisContact = user ? user->canShareThisContact() : false;
::sharedContactItems[userId].insert(item, NullType()); ::sharedContactItems[userId].insert(item, NullType());
if (canShareThisContact != (user ? user->canShareThisContact() : false)) {
Notify::PeerUpdate update(user);
update.flags |= Notify::PeerUpdateFlag::UserCanShareContact;
Notify::peerUpdatedDelayed(update);
}
} }
void unregSharedContactItem(int32 userId, HistoryItem *item) { void unregSharedContactItem(int32 userId, HistoryItem *item) {
auto user = App::userLoaded(userId);
auto canShareThisContact = user ? user->canShareThisContact() : false;
::sharedContactItems[userId].remove(item); ::sharedContactItems[userId].remove(item);
if (canShareThisContact != (user ? user->canShareThisContact() : false)) {
Notify::PeerUpdate update(user);
update.flags |= Notify::PeerUpdateFlag::UserCanShareContact;
Notify::peerUpdatedDelayed(update);
}
} }
const SharedContactItems &sharedContactItems() { const SharedContactItems &sharedContactItems() {

View file

@ -5034,12 +5034,14 @@ void HistoryWidget::onBroadcastSilentChange() {
} }
void HistoryWidget::onShareContact(const PeerId &peer, UserData *contact) { void HistoryWidget::onShareContact(const PeerId &peer, UserData *contact) {
if (!contact || contact->phone.isEmpty()) return; auto phone = contact->phone;
if (phone.isEmpty()) phone = App::phoneFromSharedContact(peerToUser(contact->id));
if (!contact || phone.isEmpty()) return;
Ui::showPeerHistory(peer, ShowAtTheEndMsgId); Ui::showPeerHistory(peer, ShowAtTheEndMsgId);
if (!_history) return; if (!_history) return;
shareContact(peer, contact->phone, contact->firstName, contact->lastName, replyToId(), peerToUser(contact->id)); shareContact(peer, phone, contact->firstName, contact->lastName, replyToId(), peerToUser(contact->id));
} }
void HistoryWidget::shareContact(const PeerId &peer, const QString &phone, const QString &fname, const QString &lname, MsgId replyTo, int32 userId) { void HistoryWidget::shareContact(const PeerId &peer, const QString &phone, const QString &fname, const QString &lname, MsgId replyTo, int32 userId) {

View file

@ -35,12 +35,14 @@ enum class PeerUpdateFlag {
PhotoChanged = 0x00000004U, PhotoChanged = 0x00000004U,
UserCanShareContact = 0x00010000U, UserCanShareContact = 0x00010000U,
UserIsContact = 0x00020000U,
ChatCanEdit = 0x00010000U, ChatCanEdit = 0x00010000U,
ChannelAmIn = 0x00010000U, ChannelAmIn = 0x00010000U,
ChannelCanEditPhoto = 0x00020000U, ChannelAmEditor = 0x00020000U,
ChannelCanAddMembers = 0x00040000U, ChannelCanEditPhoto = 0x00040000U,
ChannelCanAddMembers = 0x00080000U,
}; };
Q_DECLARE_FLAGS(PeerUpdateFlags, PeerUpdateFlag); Q_DECLARE_FLAGS(PeerUpdateFlags, PeerUpdateFlag);
Q_DECLARE_OPERATORS_FOR_FLAGS(PeerUpdateFlags); Q_DECLARE_OPERATORS_FOR_FLAGS(PeerUpdateFlags);

View file

@ -26,6 +26,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "mainwidget.h" #include "mainwidget.h"
#include "boxes/addcontactbox.h" #include "boxes/addcontactbox.h"
#include "boxes/confirmbox.h" #include "boxes/confirmbox.h"
#include "observer_peer.h"
namespace Profile { namespace Profile {
@ -60,6 +61,15 @@ private:
}; };
namespace {
const Notify::PeerUpdateFlags ButtonsUpdateFlags = Notify::PeerUpdateFlag::UserCanShareContact
| Notify::PeerUpdateFlag::UserIsContact
| Notify::PeerUpdateFlag::ChatCanEdit
| Notify::PeerUpdateFlag::ChannelAmEditor;
} // namespace
FixedBar::FixedBar(QWidget *parent, PeerData *peer) : TWidget(parent) FixedBar::FixedBar(QWidget *parent, PeerData *peer) : TWidget(parent)
, _peer(peer) , _peer(peer)
, _peerUser(peer->asUser()) , _peerUser(peer->asUser())
@ -70,9 +80,20 @@ FixedBar::FixedBar(QWidget *parent, PeerData *peer) : TWidget(parent)
_backButton->moveToLeft(0, 0); _backButton->moveToLeft(0, 0);
connect(_backButton, SIGNAL(clicked()), this, SLOT(onBack())); connect(_backButton, SIGNAL(clicked()), this, SLOT(onBack()));
Notify::registerPeerObserver(ButtonsUpdateFlags, this, &FixedBar::notifyPeerUpdate);
refreshRightActions(); refreshRightActions();
} }
void FixedBar::notifyPeerUpdate(const Notify::PeerUpdate &update) {
if (update.peer != _peer) {
return;
}
if ((update.flags & ButtonsUpdateFlags) != 0) {
refreshRightActions();
}
}
void FixedBar::refreshRightActions() { void FixedBar::refreshRightActions() {
_currentAction = 0; _currentAction = 0;
if (_peerUser) { if (_peerUser) {
@ -92,13 +113,14 @@ void FixedBar::refreshRightActions() {
} }
void FixedBar::setUserActions() { void FixedBar::setUserActions() {
if (_peerUser->contact > 0) { if (_peerUser->canShareThisContact()) {
addRightAction(RightActionType::ShareContact, lang(lng_profile_top_bar_share_contact), SLOT(onShareContact()));
}
if (_peerUser->isContact()) {
addRightAction(RightActionType::EditContact, lang(lng_profile_edit_contact), SLOT(onEditContact())); addRightAction(RightActionType::EditContact, lang(lng_profile_edit_contact), SLOT(onEditContact()));
addRightAction(RightActionType::DeleteContact, lang(lng_profile_delete_contact), SLOT(onDeleteContact())); addRightAction(RightActionType::DeleteContact, lang(lng_profile_delete_contact), SLOT(onDeleteContact()));
addRightAction(RightActionType::ShareContact, lang(lng_profile_top_bar_share_contact), SLOT(onShareContact())); } else if (_peerUser->canAddContact()) {
} else if (_peerUser->contact == 0 || !App::phoneFromSharedContact(peerToUser(_peer->id)).isEmpty()) {
addRightAction(RightActionType::AddContact, lang(lng_profile_add_contact), SLOT(onAddContact())); addRightAction(RightActionType::AddContact, lang(lng_profile_add_contact), SLOT(onAddContact()));
addRightAction(RightActionType::ShareContact, lang(lng_profile_top_bar_share_contact), SLOT(onShareContact()));
} }
} }
@ -129,9 +151,10 @@ void FixedBar::addRightAction(RightActionType type, const QString &text, const c
} }
} else { } else {
t_assert(_rightActions.size() == _currentAction); t_assert(_rightActions.size() == _currentAction);
_rightActions.push_back({}); _rightActions.push_back(RightAction());
} }
_rightActions[_currentAction].type = type; _rightActions[_currentAction].type = type;
delete _rightActions[_currentAction].button;
_rightActions[_currentAction].button = new FlatButton(this, text, st::profileFixedBarButton); _rightActions[_currentAction].button = new FlatButton(this, text, st::profileFixedBarButton);
connect(_rightActions[_currentAction].button, SIGNAL(clicked()), this, slot); connect(_rightActions[_currentAction].button, SIGNAL(clicked()), this, slot);
bool showButton = !_animatingMode && (type != RightActionType::ShareContact || !_hideShareContactButton); bool showButton = !_animatingMode && (type != RightActionType::ShareContact || !_hideShareContactButton);
@ -235,7 +258,7 @@ void FixedBar::setHideShareContactButton(bool hideButton) {
void FixedBar::applyHideShareContactButton() { void FixedBar::applyHideShareContactButton() {
for_const (auto &action, _rightActions) { for_const (auto &action, _rightActions) {
if (action.type == RightActionType::ShareContact) { if (action.type == RightActionType::ShareContact) {
action.button->setVisible(_hideShareContactButton); action.button->setVisible(!_hideShareContactButton);
} }
} }
} }

View file

@ -20,11 +20,17 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
*/ */
#pragma once #pragma once
#include "core/observer.h"
namespace Notify {
struct PeerUpdate;
} // namespace Notify
namespace Profile { namespace Profile {
class BackButton; class BackButton;
class FixedBar final : public TWidget { class FixedBar final : public TWidget, public Notify::Observer {
Q_OBJECT Q_OBJECT
public: public:
@ -57,6 +63,8 @@ private slots:
void onLeaveGroupSure(); void onLeaveGroupSure();
private: private:
void notifyPeerUpdate(const Notify::PeerUpdate &update);
void refreshRightActions(); void refreshRightActions();
void setUserActions(); void setUserActions();
void setChatActions(); void setChatActions();
@ -64,6 +72,7 @@ private:
void setChannelActions(); void setChannelActions();
enum class RightActionType { enum class RightActionType {
None,
EditChannel, EditChannel,
EditGroup, EditGroup,
LeaveGroup, LeaveGroup,
@ -86,8 +95,8 @@ private:
int _currentAction = 0; int _currentAction = 0;
struct RightAction { struct RightAction {
RightActionType type; RightActionType type = RightActionType::None;
FlatButton *button; FlatButton *button = nullptr;
}; };
QList<RightAction> _rightActions; QList<RightAction> _rightActions;

View file

@ -109,7 +109,7 @@ void Widget::resizeEvent(QResizeEvent *e) {
// _inner->resizeToWidth(scrollSize.width(), _scroll->height()); // _inner->resizeToWidth(scrollSize.width(), _scroll->height());
_inner->resizeToWidth(scrollSize.width(), _scroll->height() * 2); // testing _inner->resizeToWidth(scrollSize.width(), _scroll->height() * 2); // testing
} }
_fixedBar->setHideShareContactButton(!_inner->shareContactButtonShown()); _fixedBar->setHideShareContactButton(_inner->shareContactButtonShown());
if (!_scroll->isHidden()) { if (!_scroll->isHidden()) {
if (topDelta()) { if (topDelta()) {

View file

@ -198,6 +198,10 @@ const Text &BotCommand::descriptionText() const {
return _descriptionText; return _descriptionText;
} }
bool UserData::canShareThisContact() const {
return canShareThisContactFast() || !App::phoneFromSharedContact(peerToUser(id)).isEmpty();
}
void UserData::setPhoto(const MTPUserProfilePhoto &p) { // see Local::readPeer as well void UserData::setPhoto(const MTPUserProfilePhoto &p) { // see Local::readPeer as well
PhotoId newPhotoId = photoId; PhotoId newPhotoId = photoId;
ImagePtr newPhoto = _userpic; ImagePtr newPhoto = _userpic;
@ -490,7 +494,7 @@ void ChannelData::flagsUpdated() {
} }
} else if (mgInfo) { } else if (mgInfo) {
delete mgInfo; delete mgInfo;
mgInfo = 0; mgInfo = nullptr;
} }
} }

View file

@ -429,8 +429,20 @@ public:
bool canWrite() const { bool canWrite() const {
return access != UserNoAccess; return access != UserNoAccess;
} }
bool canShareThisContact() const { bool isContact() const {
return contact >= 0; return (contact > 0);
}
bool canShareThisContact() const;
bool canAddContact() const {
return canShareThisContact() && !isContact();
}
// In feedUsers() we check only that.
// When actually trying to share contact we perform
// a full check by canShareThisContact() call.
bool canShareThisContactFast() const {
return !phone.isEmpty();
} }
MTPInputUser inputUser; MTPInputUser inputUser;

View file

@ -41,7 +41,7 @@ void SectionWidget::setGeometryWithTopMoved(const QRect &newGeometry, int topDel
} }
void SectionWidget::showAnimated(SlideDirection direction, const SectionSlideParams &params) { void SectionWidget::showAnimated(SlideDirection direction, const SectionSlideParams &params) {
t_assert(_showAnimation == nullptr); if (_showAnimation) return;
showChildren(); showChildren();
auto myContentCache = grabForShowAnimation(params); auto myContentCache = grabForShowAnimation(params);
@ -69,6 +69,7 @@ void SectionWidget::paintEvent(QPaintEvent *e) {
} }
void SectionWidget::showFinished() { void SectionWidget::showFinished() {
_showAnimation.reset();
if (isHidden()) return; if (isHidden()) return;
App::app()->mtpUnpause(); App::app()->mtpUnpause();