Show info about request chat admin incoming message.
This commit is contained in:
		
							parent
							
								
									bdc43c0aea
								
							
						
					
					
						commit
						8d66680a96
					
				
					 10 changed files with 244 additions and 100 deletions
				
			
		| 
						 | 
				
			
			@ -1537,6 +1537,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 | 
			
		|||
"lng_new_contact_add_name" = "Add {user} to contacts";
 | 
			
		||||
"lng_new_contact_add_done" = "{user} is now in your contact list.";
 | 
			
		||||
"lng_new_contact_unarchive" = "Unarchive";
 | 
			
		||||
"lng_new_contact_from_request_channel" = "{user} is an admin of {name}, a channel you requested to join.";
 | 
			
		||||
"lng_new_contact_from_request_group" = "{user} is an admin of {name}, a group you requested to join.";
 | 
			
		||||
"lng_from_request_title_channel" = "Chat with channel's admin";
 | 
			
		||||
"lng_from_request_title_group" = "Chat with group's admin";
 | 
			
		||||
"lng_from_request_body" = "You received this message because you requested to join {name} on {date}.";
 | 
			
		||||
"lng_from_request_understand" = "I understand";
 | 
			
		||||
"lng_cant_send_to_not_contact" = "Sorry, you can only send messages to\nmutual contacts at the moment.\n{more_info}";
 | 
			
		||||
"lng_cant_invite_not_contact" = "Sorry, you can only add mutual contacts\nto groups at the moment.\n{more_info}";
 | 
			
		||||
"lng_cant_more_info" = "More info »";
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -561,6 +561,9 @@ void PeerData::checkFolder(FolderId folderId) {
 | 
			
		|||
 | 
			
		||||
void PeerData::setSettings(const MTPPeerSettings &data) {
 | 
			
		||||
	data.match([&](const MTPDpeerSettings &data) {
 | 
			
		||||
		_requestChatTitle = data.vrequest_chat_title().value_or_empty();
 | 
			
		||||
		_requestChatDate = data.vrequest_chat_date().value_or_empty();
 | 
			
		||||
 | 
			
		||||
		using Flag = PeerSetting;
 | 
			
		||||
		setSettings((data.is_add_contact() ? Flag::AddContact : Flag())
 | 
			
		||||
			| (data.is_autoarchived() ? Flag::AutoArchived : Flag())
 | 
			
		||||
| 
						 | 
				
			
			@ -571,7 +574,11 @@ void PeerData::setSettings(const MTPPeerSettings &data) {
 | 
			
		|||
				: Flag())
 | 
			
		||||
			//| (data.is_report_geo() ? Flag::ReportGeo : Flag())
 | 
			
		||||
			| (data.is_report_spam() ? Flag::ReportSpam : Flag())
 | 
			
		||||
			| (data.is_share_contact() ? Flag::ShareContact : Flag()));
 | 
			
		||||
			| (data.is_share_contact() ? Flag::ShareContact : Flag())
 | 
			
		||||
			| (data.vrequest_chat_title() ? Flag::RequestChat : Flag())
 | 
			
		||||
			| (data.is_request_chat_broadcast()
 | 
			
		||||
				? Flag::RequestChatIsBroadcast
 | 
			
		||||
				: Flag()));
 | 
			
		||||
	});
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -199,7 +199,9 @@ enum class PeerSetting {
 | 
			
		|||
	ShareContact = (1 << 3),
 | 
			
		||||
	NeedContactsException = (1 << 4),
 | 
			
		||||
	AutoArchived = (1 << 5),
 | 
			
		||||
	Unknown = (1 << 6),
 | 
			
		||||
	RequestChat = (1 << 6),
 | 
			
		||||
	RequestChatIsBroadcast = (1 << 7),
 | 
			
		||||
	Unknown = (1 << 8),
 | 
			
		||||
};
 | 
			
		||||
inline constexpr bool is_flag_type(PeerSetting) { return true; };
 | 
			
		||||
using PeerSettings = base::flags<PeerSetting>;
 | 
			
		||||
| 
						 | 
				
			
			@ -403,7 +405,7 @@ public:
 | 
			
		|||
 | 
			
		||||
	// Returns true if about text was changed.
 | 
			
		||||
	bool setAbout(const QString &newAbout);
 | 
			
		||||
	const QString &about() const {
 | 
			
		||||
	[[nodiscard]] const QString &about() const {
 | 
			
		||||
		return _about;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -412,16 +414,22 @@ public:
 | 
			
		|||
	void setSettings(PeerSettings which) {
 | 
			
		||||
		_settings.set(which);
 | 
			
		||||
	}
 | 
			
		||||
	auto settings() const {
 | 
			
		||||
	[[nodiscard]] auto settings() const {
 | 
			
		||||
		return (_settings.current() & PeerSetting::Unknown)
 | 
			
		||||
			? std::nullopt
 | 
			
		||||
			: std::make_optional(_settings.current());
 | 
			
		||||
	}
 | 
			
		||||
	auto settingsValue() const {
 | 
			
		||||
	[[nodiscard]] auto settingsValue() const {
 | 
			
		||||
		return (_settings.current() & PeerSetting::Unknown)
 | 
			
		||||
			? _settings.changes()
 | 
			
		||||
			: (_settings.value() | rpl::type_erased());
 | 
			
		||||
	}
 | 
			
		||||
	[[nodiscard]] QString requestChatTitle() const {
 | 
			
		||||
		return _requestChatTitle;
 | 
			
		||||
	}
 | 
			
		||||
	[[nodiscard]] TimeId requestChatDate() const {
 | 
			
		||||
		return _requestChatDate;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void setSettings(const MTPPeerSettings &data);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -510,6 +518,9 @@ private:
 | 
			
		|||
	BlockStatus _blockStatus = BlockStatus::Unknown;
 | 
			
		||||
	LoadedStatus _loadedStatus = LoadedStatus::Not;
 | 
			
		||||
 | 
			
		||||
	QString _requestChatTitle;
 | 
			
		||||
	TimeId _requestChatDate = 0;
 | 
			
		||||
 | 
			
		||||
	QString _about;
 | 
			
		||||
	QString _themeEmoticon;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7326,10 +7326,6 @@ void HistoryWidget::paintEvent(QPaintEvent *e) {
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QRect HistoryWidget::historyRect() const {
 | 
			
		||||
	return _scroll->geometry();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QPoint HistoryWidget::clampMousePosition(QPoint point) {
 | 
			
		||||
	if (point.x() < 0) {
 | 
			
		||||
		point.setX(0);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -157,8 +157,6 @@ public:
 | 
			
		|||
	void firstLoadMessages();
 | 
			
		||||
	void delayedShowAt(MsgId showAtMsgId);
 | 
			
		||||
 | 
			
		||||
	QRect historyRect() const;
 | 
			
		||||
 | 
			
		||||
	void updateFieldPlaceholder();
 | 
			
		||||
	bool updateStickersByEmoji();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,6 +15,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 | 
			
		|||
#include "ui/toast/toast.h"
 | 
			
		||||
#include "ui/text/format_values.h" // Ui::FormatPhone
 | 
			
		||||
#include "ui/text/text_utilities.h"
 | 
			
		||||
#include "ui/boxes/confirm_box.h"
 | 
			
		||||
#include "ui/layers/generic_box.h"
 | 
			
		||||
#include "data/data_peer.h"
 | 
			
		||||
#include "data/data_user.h"
 | 
			
		||||
#include "data/data_chat.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -26,10 +28,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 | 
			
		|||
#include "apiwrap.h"
 | 
			
		||||
#include "api/api_blocked_peers.h"
 | 
			
		||||
#include "main/main_session.h"
 | 
			
		||||
#include "ui/boxes/confirm_box.h"
 | 
			
		||||
#include "base/unixtime.h"
 | 
			
		||||
#include "boxes/peers/edit_contact_box.h"
 | 
			
		||||
#include "styles/style_chat.h"
 | 
			
		||||
#include "styles/style_layers.h"
 | 
			
		||||
#include "styles/style_info.h"
 | 
			
		||||
 | 
			
		||||
namespace HistoryView {
 | 
			
		||||
namespace {
 | 
			
		||||
| 
						 | 
				
			
			@ -56,7 +59,73 @@ bool BarCurrentlyHidden(not_null<PeerData*> peer) {
 | 
			
		|||
 | 
			
		||||
} // namespace
 | 
			
		||||
 | 
			
		||||
ContactStatus::Bar::Bar(QWidget *parent, const QString &name)
 | 
			
		||||
class ContactStatus::BgButton final : public Ui::RippleButton {
 | 
			
		||||
public:
 | 
			
		||||
	BgButton(QWidget *parent, const style::FlatButton &st);
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
	void paintEvent(QPaintEvent *e) override;
 | 
			
		||||
 | 
			
		||||
	void onStateChanged(State was, StateChangeSource source) override;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	const style::FlatButton &_st;
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class ContactStatus::Bar final : public Ui::RpWidget {
 | 
			
		||||
public:
 | 
			
		||||
	Bar(QWidget *parent, const QString &name);
 | 
			
		||||
 | 
			
		||||
	void showState(State state);
 | 
			
		||||
 | 
			
		||||
	[[nodiscard]] rpl::producer<> unarchiveClicks() const;
 | 
			
		||||
	[[nodiscard]] rpl::producer<> addClicks() const;
 | 
			
		||||
	[[nodiscard]] rpl::producer<> blockClicks() const;
 | 
			
		||||
	[[nodiscard]] rpl::producer<> shareClicks() const;
 | 
			
		||||
	[[nodiscard]] rpl::producer<> reportClicks() const;
 | 
			
		||||
	[[nodiscard]] rpl::producer<> closeClicks() const;
 | 
			
		||||
	[[nodiscard]] rpl::producer<> requestInfoClicks() const;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	int resizeGetHeight(int newWidth) override;
 | 
			
		||||
 | 
			
		||||
	QString _name;
 | 
			
		||||
	object_ptr<Ui::FlatButton> _add;
 | 
			
		||||
	object_ptr<Ui::FlatButton> _unarchive;
 | 
			
		||||
	object_ptr<Ui::FlatButton> _block;
 | 
			
		||||
	object_ptr<Ui::FlatButton> _share;
 | 
			
		||||
	object_ptr<Ui::FlatButton> _report;
 | 
			
		||||
	object_ptr<Ui::IconButton> _close;
 | 
			
		||||
	object_ptr<BgButton> _requestChatBg;
 | 
			
		||||
	object_ptr<Ui::FlatLabel> _requestChatInfo;
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
ContactStatus::BgButton::BgButton(
 | 
			
		||||
	QWidget *parent,
 | 
			
		||||
	const style::FlatButton &st)
 | 
			
		||||
: RippleButton(parent, st.ripple)
 | 
			
		||||
, _st(st) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ContactStatus::BgButton::onStateChanged(
 | 
			
		||||
		State was,
 | 
			
		||||
		StateChangeSource source) {
 | 
			
		||||
	RippleButton::onStateChanged(was, source);
 | 
			
		||||
	update();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ContactStatus::BgButton::paintEvent(QPaintEvent *e) {
 | 
			
		||||
	QPainter p(this);
 | 
			
		||||
 | 
			
		||||
	p.fillRect(e->rect(), isOver() ? _st.overBgColor : _st.bgColor);
 | 
			
		||||
	paintRipple(p, 0, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ContactStatus::Bar::Bar(
 | 
			
		||||
	QWidget *parent,
 | 
			
		||||
	const QString &name)
 | 
			
		||||
: RpWidget(parent)
 | 
			
		||||
, _name(name)
 | 
			
		||||
, _add(
 | 
			
		||||
| 
						 | 
				
			
			@ -79,26 +148,46 @@ ContactStatus::Bar::Bar(QWidget *parent, const QString &name)
 | 
			
		|||
	this,
 | 
			
		||||
	QString(),
 | 
			
		||||
	st::historyContactStatusBlock)
 | 
			
		||||
, _close(this, st::historyReplyCancel) {
 | 
			
		||||
	resize(_close->size());
 | 
			
		||||
, _close(this, st::historyReplyCancel)
 | 
			
		||||
, _requestChatBg(this, st::historyContactStatusButton)
 | 
			
		||||
, _requestChatInfo(
 | 
			
		||||
		this,
 | 
			
		||||
		QString(),
 | 
			
		||||
		st::historyContactStatusLabel) {
 | 
			
		||||
	_requestChatInfo->setAttribute(Qt::WA_TransparentForMouseEvents);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ContactStatus::Bar::showState(State state) {
 | 
			
		||||
	_add->setVisible(state == State::AddOrBlock || state == State::Add);
 | 
			
		||||
	_unarchive->setVisible(state == State::UnarchiveOrBlock
 | 
			
		||||
		|| state == State::UnarchiveOrReport);
 | 
			
		||||
	_block->setVisible(state == State::AddOrBlock
 | 
			
		||||
		|| state == State::UnarchiveOrBlock);
 | 
			
		||||
	_share->setVisible(state == State::SharePhoneNumber);
 | 
			
		||||
	_report->setVisible(state == State::ReportSpam
 | 
			
		||||
		|| state == State::UnarchiveOrReport);
 | 
			
		||||
	_add->setText((state == State::Add)
 | 
			
		||||
	using Type = State::Type;
 | 
			
		||||
	const auto type = state.type;
 | 
			
		||||
	_add->setVisible(type == Type::AddOrBlock || type == Type::Add);
 | 
			
		||||
	_unarchive->setVisible(type == Type::UnarchiveOrBlock
 | 
			
		||||
		|| type == Type::UnarchiveOrReport);
 | 
			
		||||
	_block->setVisible(type == Type::AddOrBlock
 | 
			
		||||
		|| type == Type::UnarchiveOrBlock);
 | 
			
		||||
	_share->setVisible(type == Type::SharePhoneNumber);
 | 
			
		||||
	_close->setVisible(type != Type::RequestChatInfo);
 | 
			
		||||
	_report->setVisible(type == Type::ReportSpam
 | 
			
		||||
		|| type == Type::UnarchiveOrReport);
 | 
			
		||||
	_requestChatInfo->setVisible(type == Type::RequestChatInfo);
 | 
			
		||||
	_requestChatBg->setVisible(type == Type::RequestChatInfo);
 | 
			
		||||
	_add->setText((type == Type::Add)
 | 
			
		||||
		? tr::lng_new_contact_add_name(tr::now, lt_user, _name).toUpper()
 | 
			
		||||
		: tr::lng_new_contact_add(tr::now).toUpper());
 | 
			
		||||
	_report->setText((state == State::ReportSpam)
 | 
			
		||||
	_report->setText((type == Type::ReportSpam)
 | 
			
		||||
		? tr::lng_report_spam_and_leave(tr::now).toUpper()
 | 
			
		||||
		: tr::lng_report_spam(tr::now).toUpper());
 | 
			
		||||
	updateButtonsGeometry();
 | 
			
		||||
	_requestChatInfo->setMarkedText(
 | 
			
		||||
		(state.requestChatIsBroadcast
 | 
			
		||||
			? tr::lng_new_contact_from_request_channel
 | 
			
		||||
			: tr::lng_new_contact_from_request_group)(
 | 
			
		||||
			tr::now,
 | 
			
		||||
			lt_user,
 | 
			
		||||
			Ui::Text::Bold(_name),
 | 
			
		||||
			lt_name,
 | 
			
		||||
			Ui::Text::Bold(state.requestChatName),
 | 
			
		||||
			Ui::Text::WithEntities));
 | 
			
		||||
	resizeToWidth(width());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
rpl::producer<> ContactStatus::Bar::unarchiveClicks() const {
 | 
			
		||||
| 
						 | 
				
			
			@ -125,16 +214,19 @@ rpl::producer<> ContactStatus::Bar::closeClicks() const {
 | 
			
		|||
	return _close->clicks() | rpl::to_empty;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ContactStatus::Bar::resizeEvent(QResizeEvent *e) {
 | 
			
		||||
	_close->moveToRight(0, 0);
 | 
			
		||||
	updateButtonsGeometry();
 | 
			
		||||
rpl::producer<> ContactStatus::Bar::requestInfoClicks() const {
 | 
			
		||||
	return _requestChatBg->clicks() | rpl::to_empty;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ContactStatus::Bar::updateButtonsGeometry() {
 | 
			
		||||
	const auto full = width();
 | 
			
		||||
int ContactStatus::Bar::resizeGetHeight(int newWidth) {
 | 
			
		||||
	_close->moveToRight(0, 0);
 | 
			
		||||
 | 
			
		||||
	const auto closeWidth = _close->width();
 | 
			
		||||
	const auto available = full - closeWidth;
 | 
			
		||||
	const auto available = newWidth - closeWidth;
 | 
			
		||||
	const auto skip = st::historyContactStatusMinSkip;
 | 
			
		||||
	if (available <= 2 * skip) {
 | 
			
		||||
		return _close->height();
 | 
			
		||||
	}
 | 
			
		||||
	const auto buttonWidth = [&](const object_ptr<Ui::FlatButton> &button) {
 | 
			
		||||
		return button->textWidth() + 2 * skip;
 | 
			
		||||
	};
 | 
			
		||||
| 
						 | 
				
			
			@ -157,18 +249,18 @@ void ContactStatus::Bar::updateButtonsGeometry() {
 | 
			
		|||
			thatWidth + closeWidth - available,
 | 
			
		||||
			0,
 | 
			
		||||
			closeWidth);
 | 
			
		||||
		placeButton(button, full, margin);
 | 
			
		||||
		placeButton(button, newWidth, margin);
 | 
			
		||||
	};
 | 
			
		||||
	const auto &leftButton = _unarchive->isHidden() ? _add : _unarchive;
 | 
			
		||||
	const auto &rightButton = _block->isHidden() ? _report : _block;
 | 
			
		||||
	if (!leftButton->isHidden() && !rightButton->isHidden()) {
 | 
			
		||||
		const auto leftWidth = buttonWidth(leftButton);
 | 
			
		||||
		const auto rightWidth = buttonWidth(rightButton);
 | 
			
		||||
		const auto half = full / 2;
 | 
			
		||||
		const auto half = newWidth / 2;
 | 
			
		||||
		if (leftWidth <= half
 | 
			
		||||
			&& rightWidth + 2 * closeWidth <= full - half) {
 | 
			
		||||
			&& rightWidth + 2 * closeWidth <= newWidth - half) {
 | 
			
		||||
			placeButton(leftButton, half);
 | 
			
		||||
			placeButton(rightButton, full - half);
 | 
			
		||||
			placeButton(rightButton, newWidth - half);
 | 
			
		||||
		} else if (leftWidth + rightWidth <= available) {
 | 
			
		||||
			const auto margin = std::clamp(
 | 
			
		||||
				leftWidth + rightWidth + closeWidth - available,
 | 
			
		||||
| 
						 | 
				
			
			@ -177,22 +269,31 @@ void ContactStatus::Bar::updateButtonsGeometry() {
 | 
			
		|||
			const auto realBlockWidth = rightWidth + 2 * closeWidth - margin;
 | 
			
		||||
			if (leftWidth > realBlockWidth) {
 | 
			
		||||
				placeButton(leftButton, leftWidth);
 | 
			
		||||
				placeButton(rightButton, full - leftWidth, margin);
 | 
			
		||||
				placeButton(rightButton, newWidth - leftWidth, margin);
 | 
			
		||||
			} else {
 | 
			
		||||
				placeButton(leftButton, full - realBlockWidth);
 | 
			
		||||
				placeButton(leftButton, newWidth - realBlockWidth);
 | 
			
		||||
				placeButton(rightButton, realBlockWidth, margin);
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			const auto forLeft = (available * leftWidth)
 | 
			
		||||
				/ (leftWidth + rightWidth);
 | 
			
		||||
			placeButton(leftButton, forLeft);
 | 
			
		||||
			placeButton(rightButton, full - forLeft, closeWidth);
 | 
			
		||||
			placeButton(rightButton, newWidth - forLeft, closeWidth);
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		placeOne(_add);
 | 
			
		||||
		placeOne(_share);
 | 
			
		||||
		placeOne(_report);
 | 
			
		||||
	}
 | 
			
		||||
	if (_requestChatInfo->isHidden()) {
 | 
			
		||||
		return _close->height();
 | 
			
		||||
	}
 | 
			
		||||
	const auto vskip = st::topBarArrowPadding.top();
 | 
			
		||||
	_requestChatInfo->resizeToWidth(available - 2 * skip);
 | 
			
		||||
	_requestChatInfo->move(skip, vskip);
 | 
			
		||||
	const auto newHeight = _requestChatInfo->height() + 2 * vskip;
 | 
			
		||||
	_requestChatBg->setGeometry(0, 0, newWidth, newHeight);
 | 
			
		||||
	return newHeight;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ContactStatus::ContactStatus(
 | 
			
		||||
| 
						 | 
				
			
			@ -231,6 +332,7 @@ void ContactStatus::setupWidgets(not_null<Ui::RpWidget*> parent) {
 | 
			
		|||
auto ContactStatus::PeerState(not_null<PeerData*> peer)
 | 
			
		||||
-> rpl::producer<State> {
 | 
			
		||||
	using SettingsChange = PeerData::Settings::Change;
 | 
			
		||||
	using Type = State::Type;
 | 
			
		||||
	if (const auto user = peer->asUser()) {
 | 
			
		||||
		using FlagsChange = UserData::Flags::Change;
 | 
			
		||||
		using Flag = UserDataFlag;
 | 
			
		||||
| 
						 | 
				
			
			@ -245,34 +347,43 @@ auto ContactStatus::PeerState(not_null<PeerData*> peer)
 | 
			
		|||
			user->settingsValue()
 | 
			
		||||
		) | rpl::map([=](
 | 
			
		||||
				FlagsChange flags,
 | 
			
		||||
				SettingsChange settings) {
 | 
			
		||||
				SettingsChange settings) -> State {
 | 
			
		||||
			if (flags.value & Flag::Blocked) {
 | 
			
		||||
				return State::None;
 | 
			
		||||
				return { Type::None };
 | 
			
		||||
			} else if (user->isContact()) {
 | 
			
		||||
				if (settings.value & PeerSetting::ShareContact) {
 | 
			
		||||
					return State::SharePhoneNumber;
 | 
			
		||||
					return { Type::SharePhoneNumber };
 | 
			
		||||
				} else {
 | 
			
		||||
					return State::None;
 | 
			
		||||
					return { Type::None };
 | 
			
		||||
				}
 | 
			
		||||
			} else if (settings.value & PeerSetting::RequestChat) {
 | 
			
		||||
				return {
 | 
			
		||||
					.type = Type::RequestChatInfo,
 | 
			
		||||
					.requestChatName = peer->requestChatTitle(),
 | 
			
		||||
					.requestChatIsBroadcast = !!(settings.value
 | 
			
		||||
						& PeerSetting::RequestChatIsBroadcast),
 | 
			
		||||
					.requestDate = peer->requestChatDate(),
 | 
			
		||||
				};
 | 
			
		||||
			} else if (settings.value & PeerSetting::AutoArchived) {
 | 
			
		||||
				return State::UnarchiveOrBlock;
 | 
			
		||||
				return { Type::UnarchiveOrBlock };
 | 
			
		||||
			} else if (settings.value & PeerSetting::BlockContact) {
 | 
			
		||||
				return State::AddOrBlock;
 | 
			
		||||
				return { Type::AddOrBlock };
 | 
			
		||||
			} else if (settings.value & PeerSetting::AddContact) {
 | 
			
		||||
				return State::Add;
 | 
			
		||||
				return { Type::Add };
 | 
			
		||||
			} else {
 | 
			
		||||
				return State::None;
 | 
			
		||||
				return { Type::None };
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return peer->settingsValue(
 | 
			
		||||
	) | rpl::map([=](SettingsChange settings) {
 | 
			
		||||
		using Type = State::Type;
 | 
			
		||||
		return (settings.value & PeerSetting::AutoArchived)
 | 
			
		||||
			? State::UnarchiveOrReport
 | 
			
		||||
			? State{ Type::UnarchiveOrReport }
 | 
			
		||||
			: (settings.value & PeerSetting::ReportSpam)
 | 
			
		||||
			? State::ReportSpam
 | 
			
		||||
			: State::None;
 | 
			
		||||
			? State{ Type::ReportSpam }
 | 
			
		||||
			: State{ Type::None };
 | 
			
		||||
	});
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -285,7 +396,7 @@ void ContactStatus::setupState(not_null<PeerData*> peer) {
 | 
			
		|||
		peer
 | 
			
		||||
	) | rpl::start_with_next([=](State state) {
 | 
			
		||||
		_state = state;
 | 
			
		||||
		if (state == State::None) {
 | 
			
		||||
		if (state.type == State::Type::None) {
 | 
			
		||||
			_bar.hide(anim::type::normal);
 | 
			
		||||
		} else {
 | 
			
		||||
			_bar.entity()->showState(state);
 | 
			
		||||
| 
						 | 
				
			
			@ -303,6 +414,7 @@ void ContactStatus::setupHandlers(not_null<PeerData*> peer) {
 | 
			
		|||
	setupUnarchiveHandler(peer);
 | 
			
		||||
	setupReportHandler(peer);
 | 
			
		||||
	setupCloseHandler(peer);
 | 
			
		||||
	setupRequestInfoHandler(peer);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ContactStatus::setupAddHandler(not_null<UserData*> user) {
 | 
			
		||||
| 
						 | 
				
			
			@ -420,8 +532,44 @@ void ContactStatus::setupCloseHandler(not_null<PeerData*> peer) {
 | 
			
		|||
	}, _bar.lifetime());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ContactStatus::setupRequestInfoHandler(not_null<PeerData*> peer) {
 | 
			
		||||
	const auto request = _bar.lifetime().make_state<mtpRequestId>(0);
 | 
			
		||||
	_bar.entity()->requestInfoClicks(
 | 
			
		||||
	) | rpl::filter([=] {
 | 
			
		||||
		return !(*request);
 | 
			
		||||
	}) | rpl::start_with_next([=] {
 | 
			
		||||
		_controller->show(Box([=](not_null<Ui::GenericBox*> box) {
 | 
			
		||||
			box->setTitle((_state.requestChatIsBroadcast
 | 
			
		||||
				? tr::lng_from_request_title_channel
 | 
			
		||||
				: tr::lng_from_request_title_group)());
 | 
			
		||||
 | 
			
		||||
			box->addRow(object_ptr<Ui::FlatLabel>(
 | 
			
		||||
				box,
 | 
			
		||||
				tr::lng_from_request_body(
 | 
			
		||||
					lt_name,
 | 
			
		||||
					rpl::single(Ui::Text::Bold(_state.requestChatName)),
 | 
			
		||||
					lt_date,
 | 
			
		||||
					rpl::single(langDateTimeFull(
 | 
			
		||||
						base::unixtime::parse(_state.requestDate)
 | 
			
		||||
					)) | Ui::Text::ToWithEntities(),
 | 
			
		||||
					Ui::Text::WithEntities),
 | 
			
		||||
				st::boxLabel));
 | 
			
		||||
 | 
			
		||||
			box->addButton(tr::lng_from_request_understand(), [=] {
 | 
			
		||||
				if (*request) {
 | 
			
		||||
					return;
 | 
			
		||||
				}
 | 
			
		||||
				peer->setSettings(0);
 | 
			
		||||
				*request = peer->session().api().request(
 | 
			
		||||
					MTPmessages_HidePeerSettingsBar(peer->input)
 | 
			
		||||
				).send();
 | 
			
		||||
			});
 | 
			
		||||
		}));
 | 
			
		||||
	}, _bar.lifetime());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ContactStatus::show() {
 | 
			
		||||
	const auto visible = (_state != State::None);
 | 
			
		||||
	const auto visible = (_state.type != State::Type::None);
 | 
			
		||||
	if (!_shown) {
 | 
			
		||||
		_shown = true;
 | 
			
		||||
		if (visible) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,6 +18,7 @@ class SessionController;
 | 
			
		|||
namespace Ui {
 | 
			
		||||
class FlatButton;
 | 
			
		||||
class IconButton;
 | 
			
		||||
class FlatLabel;
 | 
			
		||||
} // namespace Ui
 | 
			
		||||
 | 
			
		||||
namespace HistoryView {
 | 
			
		||||
| 
						 | 
				
			
			@ -33,15 +34,19 @@ public:
 | 
			
		|||
	void raise();
 | 
			
		||||
 | 
			
		||||
	void move(int x, int y);
 | 
			
		||||
	int height() const;
 | 
			
		||||
	rpl::producer<int> heightValue() const;
 | 
			
		||||
	[[nodiscard]] int height() const;
 | 
			
		||||
	[[nodiscard]] rpl::producer<int> heightValue() const;
 | 
			
		||||
 | 
			
		||||
	rpl::lifetime &lifetime() {
 | 
			
		||||
	[[nodiscard]] rpl::lifetime &lifetime() {
 | 
			
		||||
		return _lifetime;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	enum class State {
 | 
			
		||||
	class Bar;
 | 
			
		||||
	class BgButton;
 | 
			
		||||
 | 
			
		||||
	struct State {
 | 
			
		||||
		enum class Type {
 | 
			
		||||
			None,
 | 
			
		||||
			ReportSpam,
 | 
			
		||||
			Add,
 | 
			
		||||
| 
						 | 
				
			
			@ -49,35 +54,12 @@ private:
 | 
			
		|||
			UnarchiveOrBlock,
 | 
			
		||||
			UnarchiveOrReport,
 | 
			
		||||
			SharePhoneNumber,
 | 
			
		||||
			RequestChatInfo,
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
	class Bar : public Ui::RpWidget {
 | 
			
		||||
	public:
 | 
			
		||||
		Bar(QWidget *parent, const QString &name);
 | 
			
		||||
 | 
			
		||||
		void showState(State state);
 | 
			
		||||
 | 
			
		||||
		rpl::producer<> unarchiveClicks() const;
 | 
			
		||||
		rpl::producer<> addClicks() const;
 | 
			
		||||
		rpl::producer<> blockClicks() const;
 | 
			
		||||
		rpl::producer<> shareClicks() const;
 | 
			
		||||
		rpl::producer<> reportClicks() const;
 | 
			
		||||
		rpl::producer<> closeClicks() const;
 | 
			
		||||
 | 
			
		||||
	protected:
 | 
			
		||||
		void resizeEvent(QResizeEvent *e) override;
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
		void updateButtonsGeometry();
 | 
			
		||||
 | 
			
		||||
		QString _name;
 | 
			
		||||
		object_ptr<Ui::FlatButton> _add;
 | 
			
		||||
		object_ptr<Ui::FlatButton> _unarchive;
 | 
			
		||||
		object_ptr<Ui::FlatButton> _block;
 | 
			
		||||
		object_ptr<Ui::FlatButton> _share;
 | 
			
		||||
		object_ptr<Ui::FlatButton> _report;
 | 
			
		||||
		object_ptr<Ui::IconButton> _close;
 | 
			
		||||
 | 
			
		||||
		Type type = Type::None;
 | 
			
		||||
		QString requestChatName;
 | 
			
		||||
		bool requestChatIsBroadcast = false;
 | 
			
		||||
		TimeId requestDate = 0;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	void setupWidgets(not_null<Ui::RpWidget*> parent);
 | 
			
		||||
| 
						 | 
				
			
			@ -89,11 +71,12 @@ private:
 | 
			
		|||
	void setupUnarchiveHandler(not_null<PeerData*> peer);
 | 
			
		||||
	void setupReportHandler(not_null<PeerData*> peer);
 | 
			
		||||
	void setupCloseHandler(not_null<PeerData*> peer);
 | 
			
		||||
	void setupRequestInfoHandler(not_null<PeerData*> peer);
 | 
			
		||||
 | 
			
		||||
	static rpl::producer<State> PeerState(not_null<PeerData*> peer);
 | 
			
		||||
 | 
			
		||||
	const not_null<Window::SessionController*> _controller;
 | 
			
		||||
	State _state = State::None;
 | 
			
		||||
	State _state;
 | 
			
		||||
	Ui::SlideWrap<Bar> _bar;
 | 
			
		||||
	Ui::PlainShadow _shadow;
 | 
			
		||||
	bool _shown = false;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1857,13 +1857,6 @@ void MainWidget::orderWidgets() {
 | 
			
		|||
	if (_hider) _hider->raise();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QRect MainWidget::historyRect() const {
 | 
			
		||||
	QRect r(_history->historyRect());
 | 
			
		||||
	r.moveLeft(r.left() + _history->x());
 | 
			
		||||
	r.moveTop(r.top() + _history->y());
 | 
			
		||||
	return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QPixmap MainWidget::grabForShowAnimation(const Window::SectionSlideParams ¶ms) {
 | 
			
		||||
	QPixmap result;
 | 
			
		||||
	floatPlayerHideAll();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -151,7 +151,6 @@ public:
 | 
			
		|||
	void showBackFromStack(
 | 
			
		||||
		const SectionShow ¶ms);
 | 
			
		||||
	void orderWidgets();
 | 
			
		||||
	QRect historyRect() const;
 | 
			
		||||
	QPixmap grabForShowAnimation(const Window::SectionSlideParams ¶ms);
 | 
			
		||||
	void checkMainSectionToLayer();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -268,6 +268,9 @@ historyContactStatusBlock: FlatButton(historyContactStatusButton) {
 | 
			
		|||
	color: attentionButtonFg;
 | 
			
		||||
	overColor: attentionButtonFg;
 | 
			
		||||
}
 | 
			
		||||
historyContactStatusLabel: FlatLabel(defaultFlatLabel) {
 | 
			
		||||
	minWidth: 240px;
 | 
			
		||||
}
 | 
			
		||||
historyContactStatusMinSkip: 16px;
 | 
			
		||||
 | 
			
		||||
historySendIcon: icon {{ "chat/input_send", historySendIconFg }};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue