Add 'Invite via Link' button to Add Members box.

This commit is contained in:
John Preston 2021-02-01 22:30:00 +04:00
parent 34ec1c371c
commit 5538c5eace
9 changed files with 101 additions and 12 deletions

View file

@ -827,6 +827,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_profile_delete_contact" = "Delete"; "lng_profile_delete_contact" = "Delete";
"lng_profile_set_group_photo" = "Set Photo"; "lng_profile_set_group_photo" = "Set Photo";
"lng_profile_add_participant" = "Add Members"; "lng_profile_add_participant" = "Add Members";
"lng_profile_add_via_link" = "Invite via Link";
"lng_profile_view_channel" = "View Channel"; "lng_profile_view_channel" = "View Channel";
"lng_profile_view_discussion" = "View discussion"; "lng_profile_view_discussion" = "View discussion";
"lng_profile_join_channel" = "Join Channel"; "lng_profile_join_channel" = "Join Channel";

View file

@ -906,6 +906,29 @@ pollResultsShowMore: SettingsButton(defaultSettingsButton) {
ripple: defaultRippleAnimation; ripple: defaultRippleAnimation;
} }
inviteViaLinkButton: SettingsButton(defaultSettingsButton) {
textFg: lightButtonFg;
textFgOver: lightButtonFgOver;
textBg: windowBg;
textBgOver: windowBgOver;
font: font(14px semibold);
height: 20px;
padding: margins(74px, 8px, 8px, 9px);
ripple: defaultRippleAnimation;
}
inviteViaLinkIcon: icon {{ "info/edit/group_manage_links", lightButtonFg }};
inviteViaLinkIconPosition: point(23px, 2px);
peerListWithInviteViaLink: PeerList(peerListBox) {
padding: margins(
0px,
0px,
0px,
membersMarginBottom);
}
scheduleHeight: 95px; scheduleHeight: 95px;
scheduleDateTop: 38px; scheduleDateTop: 38px;
scheduleDateField: InputField(defaultInputField) { scheduleDateField: InputField(defaultInputField) {

View file

@ -1161,11 +1161,7 @@ void PeerListContent::enterEventHook(QEvent *e) {
void PeerListContent::leaveEventHook(QEvent *e) { void PeerListContent::leaveEventHook(QEvent *e) {
setMouseTracking(false); setMouseTracking(false);
if (_mouseSelection) { mouseLeftGeometry();
setSelected(Selected());
_mouseSelection = false;
_lastMousePosition = std::nullopt;
}
} }
void PeerListContent::mouseMoveEvent(QMouseEvent *e) { void PeerListContent::mouseMoveEvent(QMouseEvent *e) {
@ -1500,6 +1496,14 @@ void PeerListContent::clearSelection() {
setSelected(Selected()); setSelected(Selected());
} }
void PeerListContent::mouseLeftGeometry() {
if (_mouseSelection) {
setSelected(Selected());
_mouseSelection = false;
_lastMousePosition = std::nullopt;
}
}
void PeerListContent::loadProfilePhotos() { void PeerListContent::loadProfilePhotos() {
if (_visibleTop >= _visibleBottom) return; if (_visibleTop >= _visibleBottom) return;

View file

@ -261,6 +261,7 @@ public:
virtual void peerListSetAboveWidget(object_ptr<TWidget> aboveWidget) = 0; virtual void peerListSetAboveWidget(object_ptr<TWidget> aboveWidget) = 0;
virtual void peerListSetAboveSearchWidget(object_ptr<TWidget> aboveWidget) = 0; virtual void peerListSetAboveSearchWidget(object_ptr<TWidget> aboveWidget) = 0;
virtual void peerListSetBelowWidget(object_ptr<TWidget> belowWidget) = 0; virtual void peerListSetBelowWidget(object_ptr<TWidget> belowWidget) = 0;
virtual void peerListMouseLeftGeometry() = 0;
virtual void peerListSetSearchMode(PeerListSearchMode mode) = 0; virtual void peerListSetSearchMode(PeerListSearchMode mode) = 0;
virtual void peerListAppendRow(std::unique_ptr<PeerListRow> row) = 0; virtual void peerListAppendRow(std::unique_ptr<PeerListRow> row) = 0;
virtual void peerListAppendSearchRow(std::unique_ptr<PeerListRow> row) = 0; virtual void peerListAppendSearchRow(std::unique_ptr<PeerListRow> row) = 0;
@ -541,6 +542,8 @@ public:
void setHideEmpty(bool hide); void setHideEmpty(bool hide);
void refreshRows(); void refreshRows();
void mouseLeftGeometry();
void setSearchMode(PeerListSearchMode mode); void setSearchMode(PeerListSearchMode mode);
void changeCheckState( void changeCheckState(
not_null<PeerListRow*> row, not_null<PeerListRow*> row,
@ -804,6 +807,9 @@ public:
void peerListSetSearchMode(PeerListSearchMode mode) override { void peerListSetSearchMode(PeerListSearchMode mode) override {
_content->setSearchMode(mode); _content->setSearchMode(mode);
} }
void peerListMouseLeftGeometry() override {
_content->mouseLeftGeometry();
}
void peerListSortRows( void peerListSortRows(
Fn<bool(const PeerListRow &a, const PeerListRow &b)> compare) override { Fn<bool(const PeerListRow &a, const PeerListRow &b)> compare) override {
_content->reorderRows([&]( _content->reorderRows([&](

View file

@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "boxes/peers/add_participants_box.h" #include "boxes/peers/add_participants_box.h"
#include "boxes/peers/edit_participant_box.h" #include "boxes/peers/edit_participant_box.h"
#include "boxes/peers/edit_peer_type_box.h"
#include "boxes/confirm_box.h" #include "boxes/confirm_box.h"
#include "lang/lang_keys.h" #include "lang/lang_keys.h"
#include "data/data_channel.h" #include "data/data_channel.h"
@ -18,15 +19,19 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_changes.h" #include "data/data_changes.h"
#include "history/history.h" #include "history/history.h"
#include "dialogs/dialogs_indexed_list.h" #include "dialogs/dialogs_indexed_list.h"
#include "ui/widgets/buttons.h"
#include "ui/wrap/padding_wrap.h"
#include "base/unixtime.h" #include "base/unixtime.h"
#include "main/main_session.h" #include "main/main_session.h"
#include "mtproto/mtproto_config.h" #include "mtproto/mtproto_config.h"
#include "mainwidget.h" #include "mainwidget.h"
#include "mainwindow.h" #include "mainwindow.h"
#include "window/window_session_controller.h" #include "window/window_session_controller.h"
#include "info/profile/info_profile_icon.h"
#include "apiwrap.h" #include "apiwrap.h"
#include "facades.h" // Ui::showPeerHistory #include "facades.h" // Ui::showPeerHistory
#include "app.h" #include "app.h"
#include "styles/style_boxes.h"
namespace { namespace {
@ -68,6 +73,9 @@ AddParticipantsBoxController::AddParticipantsBoxController(
: ContactsBoxController(&peer->session()) : ContactsBoxController(&peer->session())
, _peer(peer) , _peer(peer)
, _alreadyIn(std::move(alreadyIn)) { , _alreadyIn(std::move(alreadyIn)) {
if (needsInviteLinkButton()) {
setStyleOverrides(&st::peerListWithInviteViaLink);
}
subscribeToMigration(); subscribeToMigration();
} }
@ -166,6 +174,44 @@ void AddParticipantsBoxController::updateTitle() {
).arg(session().serverConfig().megagroupSizeMax); ).arg(session().serverConfig().megagroupSizeMax);
delegate()->peerListSetTitle(tr::lng_profile_add_participant()); delegate()->peerListSetTitle(tr::lng_profile_add_participant());
delegate()->peerListSetAdditionalTitle(rpl::single(additional)); delegate()->peerListSetAdditionalTitle(rpl::single(additional));
addInviteLinkButton();
}
bool AddParticipantsBoxController::needsInviteLinkButton() {
if (!_peer) {
return false;
} else if (const auto channel = _peer->asChannel()) {
return channel->canHaveInviteLink();
}
return _peer->asChat()->canHaveInviteLink();
}
void AddParticipantsBoxController::addInviteLinkButton() {
if (!needsInviteLinkButton()) {
return;
}
auto button = object_ptr<Ui::PaddingWrap<Ui::SettingsButton>>(
nullptr,
object_ptr<Ui::SettingsButton>(
nullptr,
tr::lng_profile_add_via_link(),
st::inviteViaLinkButton),
style::margins(0, st::membersMarginTop, 0, 0));
object_ptr<Info::Profile::FloatingIcon>(
button->entity(),
st::inviteViaLinkIcon,
st::inviteViaLinkIconPosition);
button->entity()->setClickedCallback([=] {
Ui::show(Box<EditPeerTypeBox>(_peer), Ui::LayerOption::KeepOther);
});
button->entity()->events(
) | rpl::filter([=](not_null<QEvent*> e) {
return (e->type() == QEvent::Enter);
}) | rpl::start_with_next([=] {
delegate()->peerListMouseLeftGeometry();
}, button->lifetime());
delegate()->peerListSetAboveWidget(std::move(button));
} }
bool AddParticipantsBoxController::inviteSelectedUsers( bool AddParticipantsBoxController::inviteSelectedUsers(

View file

@ -44,6 +44,7 @@ protected:
void prepareViewHook() override; void prepareViewHook() override;
std::unique_ptr<PeerListRow> createRow( std::unique_ptr<PeerListRow> createRow(
not_null<UserData*> user) override; not_null<UserData*> user) override;
virtual bool needsInviteLinkButton();
private: private:
static void Start( static void Start(
@ -52,6 +53,7 @@ private:
base::flat_set<not_null<UserData*>> &&alreadyIn, base::flat_set<not_null<UserData*>> &&alreadyIn,
bool justCreated); bool justCreated);
void addInviteLinkButton();
bool inviteSelectedUsers(not_null<PeerListBox*> box) const; bool inviteSelectedUsers(not_null<PeerListBox*> box) const;
void subscribeToMigration(); void subscribeToMigration();
int alreadyInCount() const; int alreadyInCount() const;

View file

@ -133,6 +133,8 @@ private:
QString inviteLinkText(); QString inviteLinkText();
not_null<PeerData*> _peer; not_null<PeerData*> _peer;
bool _linkOnly = false;
MTP::Sender _api; MTP::Sender _api;
std::optional<Privacy> _privacySavedValue; std::optional<Privacy> _privacySavedValue;
std::optional<QString> _usernameSavedValue; std::optional<QString> _usernameSavedValue;
@ -158,6 +160,7 @@ Controller::Controller(
std::optional<Privacy> privacySavedValue, std::optional<Privacy> privacySavedValue,
std::optional<QString> usernameSavedValue) std::optional<QString> usernameSavedValue)
: _peer(peer) : _peer(peer)
, _linkOnly(!privacySavedValue.has_value())
, _api(&_peer->session().mtp()) , _api(&_peer->session().mtp())
, _privacySavedValue(privacySavedValue) , _privacySavedValue(privacySavedValue)
, _usernameSavedValue(usernameSavedValue) , _usernameSavedValue(usernameSavedValue)
@ -174,12 +177,12 @@ void Controller::createContent() {
fillPrivaciesButtons(_wrap, _privacySavedValue); fillPrivaciesButtons(_wrap, _privacySavedValue);
// Skip. // Skip.
if (_privacySavedValue) { if (!_linkOnly) {
_wrap->add(object_ptr<Ui::BoxContentDivider>(_wrap)); _wrap->add(object_ptr<Ui::BoxContentDivider>(_wrap));
} }
// //
_wrap->add(createInviteLinkBlock()); _wrap->add(createInviteLinkBlock());
if (_privacySavedValue) { if (!_linkOnly) {
_wrap->add(createUsernameEdit()); _wrap->add(createUsernameEdit());
} }
@ -198,7 +201,9 @@ void Controller::createContent() {
//AddSkip(_wrap.get()); //AddSkip(_wrap.get());
//AddDividerText(_wrap.get(), tr::lng_group_invite_manage_about()); //AddDividerText(_wrap.get(), tr::lng_group_invite_manage_about());
if (_controls.privacy) { if (_linkOnly) {
_controls.inviteLinkWrap->show(anim::type::instant);
} else {
if (_controls.privacy->value() == Privacy::NoUsername) { if (_controls.privacy->value() == Privacy::NoUsername) {
checkUsernameAvailability(); checkUsernameAvailability();
} }
@ -209,8 +214,6 @@ void Controller::createContent() {
_controls.usernameWrap->toggle( _controls.usernameWrap->toggle(
(forShowing == Privacy::HasUsername), (forShowing == Privacy::HasUsername),
anim::type::instant); anim::type::instant);
} else {
_controls.inviteLinkWrap->show(anim::type::instant);
} }
} }
@ -248,7 +251,7 @@ void Controller::fillPrivaciesButtons(
} }
Unexpected("Peer type in Controller::createPrivaciesEdit."); Unexpected("Peer type in Controller::createPrivaciesEdit.");
}(); }();
if (!canEditUsername) { if (!canEditUsername || _linkOnly) {
return; return;
} }

View file

@ -22,7 +22,7 @@ struct SingleChoiceBoxArgs {
required<rpl::producer<QString>> title; required<rpl::producer<QString>> title;
const std::vector<QString> &options; const std::vector<QString> &options;
int initialSelection = 0; int initialSelection = 0;
required<Fn<void(int)>> callback; Fn<void(int)> callback;
const style::Checkbox *st = nullptr; const style::Checkbox *st = nullptr;
const style::Radio *radioSt = nullptr; const style::Radio *radioSt = nullptr;
}; };

View file

@ -99,6 +99,10 @@ private:
std::unique_ptr<PeerListRow> createRow( std::unique_ptr<PeerListRow> createRow(
not_null<UserData*> user) override; not_null<UserData*> user) override;
bool needsInviteLinkButton() override {
return false;
}
const not_null<const base::flat_set<not_null<UserData*>>*> _inGroup; const not_null<const base::flat_set<not_null<UserData*>>*> _inGroup;
rpl::producer<not_null<UserData*>> _discoveredInGroup; rpl::producer<not_null<UserData*>> _discoveredInGroup;