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_set_group_photo" = "Set Photo";
"lng_profile_add_participant" = "Add Members";
"lng_profile_add_via_link" = "Invite via Link";
"lng_profile_view_channel" = "View Channel";
"lng_profile_view_discussion" = "View discussion";
"lng_profile_join_channel" = "Join Channel";

View File

@ -906,6 +906,29 @@ pollResultsShowMore: SettingsButton(defaultSettingsButton) {
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;
scheduleDateTop: 38px;
scheduleDateField: InputField(defaultInputField) {

View File

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

View File

@ -261,6 +261,7 @@ public:
virtual void peerListSetAboveWidget(object_ptr<TWidget> aboveWidget) = 0;
virtual void peerListSetAboveSearchWidget(object_ptr<TWidget> aboveWidget) = 0;
virtual void peerListSetBelowWidget(object_ptr<TWidget> belowWidget) = 0;
virtual void peerListMouseLeftGeometry() = 0;
virtual void peerListSetSearchMode(PeerListSearchMode mode) = 0;
virtual void peerListAppendRow(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 refreshRows();
void mouseLeftGeometry();
void setSearchMode(PeerListSearchMode mode);
void changeCheckState(
not_null<PeerListRow*> row,
@ -804,6 +807,9 @@ public:
void peerListSetSearchMode(PeerListSearchMode mode) override {
_content->setSearchMode(mode);
}
void peerListMouseLeftGeometry() override {
_content->mouseLeftGeometry();
}
void peerListSortRows(
Fn<bool(const PeerListRow &a, const PeerListRow &b)> compare) override {
_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/edit_participant_box.h"
#include "boxes/peers/edit_peer_type_box.h"
#include "boxes/confirm_box.h"
#include "lang/lang_keys.h"
#include "data/data_channel.h"
@ -18,15 +19,19 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_changes.h"
#include "history/history.h"
#include "dialogs/dialogs_indexed_list.h"
#include "ui/widgets/buttons.h"
#include "ui/wrap/padding_wrap.h"
#include "base/unixtime.h"
#include "main/main_session.h"
#include "mtproto/mtproto_config.h"
#include "mainwidget.h"
#include "mainwindow.h"
#include "window/window_session_controller.h"
#include "info/profile/info_profile_icon.h"
#include "apiwrap.h"
#include "facades.h" // Ui::showPeerHistory
#include "app.h"
#include "styles/style_boxes.h"
namespace {
@ -68,6 +73,9 @@ AddParticipantsBoxController::AddParticipantsBoxController(
: ContactsBoxController(&peer->session())
, _peer(peer)
, _alreadyIn(std::move(alreadyIn)) {
if (needsInviteLinkButton()) {
setStyleOverrides(&st::peerListWithInviteViaLink);
}
subscribeToMigration();
}
@ -166,6 +174,44 @@ void AddParticipantsBoxController::updateTitle() {
).arg(session().serverConfig().megagroupSizeMax);
delegate()->peerListSetTitle(tr::lng_profile_add_participant());
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(

View File

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

View File

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

View File

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

View File

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