Support invite link label editing.

This commit is contained in:
John Preston 2021-10-28 16:18:49 +04:00
parent eb82664452
commit aaae5b0553
8 changed files with 63 additions and 4 deletions

View File

@ -1307,6 +1307,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_group_invite_link_expired" = "Expired";
"lng_group_invite_edit_title" = "Edit Link";
"lng_group_invite_new_title" = "New Link";
"lng_group_invite_label_header" = "Label (optional)";
"lng_group_invite_label_about" = "Add an optional link label.";
"lng_group_invite_expire_title" = "Limit by time period";
"lng_group_invite_expire_about" = "You can make the link expire after a certain time.";
"lng_group_invite_expire_never" = "No limit";
@ -2526,6 +2528,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_admin_log_edited_invite_link" = "edited invite link {link}";
"lng_admin_log_invite_link_expire_date" = "Expire date: {previous} -> {limit}";
"lng_admin_log_invite_link_usage_limit" = "Usage limit: {previous} -> {limit}";
"lng_admin_log_invite_link_label" = "Label: {previous} -> {limit}";
"lng_admin_log_invite_link_request_needed" = "Now admin approval is required to join.";
"lng_admin_log_invite_link_request_not_needed" = "Now admin approval is not required to join.";
"lng_admin_log_restricted_forever" = "indefinitely";

View File

@ -70,6 +70,7 @@ InviteLinks::InviteLinks(not_null<ApiWrap*> api) : _api(api) {
void InviteLinks::create(
not_null<PeerData*> peer,
Fn<void(Link)> done,
const QString &label,
TimeId expireDate,
int usageLimit,
bool requestApproval) {
@ -77,6 +78,7 @@ void InviteLinks::create(
peer,
std::move(done),
false,
label,
expireDate,
usageLimit,
requestApproval);
@ -86,6 +88,7 @@ void InviteLinks::performCreate(
not_null<PeerData*> peer,
Fn<void(Link)> done,
bool revokeLegacyPermanent,
const QString &label,
TimeId expireDate,
int usageLimit,
bool requestApproval) {
@ -106,6 +109,7 @@ void InviteLinks::performCreate(
MTP_flags((revokeLegacyPermanent
? Flag::f_legacy_revoke_permanent
: Flag(0))
| (!label.isEmpty() ? Flag::f_title : Flag(0))
| (expireDate ? Flag::f_expire_date : Flag(0))
| ((!requestApproval && usageLimit)
? Flag::f_usage_limit
@ -114,7 +118,7 @@ void InviteLinks::performCreate(
peer->input,
MTP_int(expireDate),
MTP_int(usageLimit),
MTPstring() // title
MTP_string(label)
)).done([=](const MTPExportedChatInvite &result) {
const auto callbacks = _createCallbacks.take(peer);
const auto link = prepend(peer, peer->session().user(), result);
@ -212,6 +216,7 @@ void InviteLinks::edit(
not_null<PeerData*> peer,
not_null<UserData*> admin,
const QString &link,
const QString &label,
TimeId expireDate,
int usageLimit,
bool requestApproval,
@ -222,6 +227,7 @@ void InviteLinks::edit(
link,
std::move(done),
false,
label,
expireDate,
usageLimit,
requestApproval);
@ -233,6 +239,7 @@ void InviteLinks::performEdit(
const QString &link,
Fn<void(Link)> done,
bool revoke,
const QString &label,
TimeId expireDate,
int usageLimit,
bool requestApproval) {
@ -253,6 +260,7 @@ void InviteLinks::performEdit(
}
using Flag = MTPmessages_EditExportedChatInvite::Flag;
const auto flags = (revoke ? Flag::f_revoked : Flag(0))
| (!revoke ? Flag::f_title : Flag(0))
| (!revoke ? Flag::f_expire_date : Flag(0))
| ((!revoke && !requestApproval) ? Flag::f_usage_limit : Flag(0))
| ((!revoke && (requestApproval || !usageLimit))
@ -265,7 +273,7 @@ void InviteLinks::performEdit(
MTP_int(expireDate),
MTP_int(usageLimit),
MTP_bool(requestApproval),
MTPstring() // title
MTP_string(label)
)).done([=](const MTPmessages_ExportedChatInvite &result) {
const auto callbacks = _editCallbacks.take(key);
const auto peer = key.peer;
@ -729,6 +737,7 @@ auto InviteLinks::parse(
return invite.match([&](const MTPDchatInviteExported &data) {
return Link{
.link = qs(data.vlink()),
.label = qs(data.vtitle().value_or_empty()),
.admin = peer->session().data().user(data.vadmin_id()),
.date = data.vdate().v,
.startDate = data.vstart_date().value_or_empty(),

View File

@ -13,6 +13,7 @@ namespace Api {
struct InviteLink {
QString link;
QString label;
not_null<UserData*> admin;
TimeId date = 0;
TimeId startDate = 0;
@ -62,6 +63,7 @@ public:
void create(
not_null<PeerData*> peer,
Fn<void(Link)> done = nullptr,
const QString &label = QString(),
TimeId expireDate = 0,
int usageLimit = 0,
bool requestApproval = false);
@ -69,6 +71,7 @@ public:
not_null<PeerData*> peer,
not_null<UserData*> admin,
const QString &link,
const QString &label,
TimeId expireDate,
int usageLimit,
bool requestApproval,
@ -180,6 +183,7 @@ private:
const QString &link,
Fn<void(Link)> done,
bool revoke,
const QString &label = QString(),
TimeId expireDate = 0,
int usageLimit = 0,
bool requestApproval = false);
@ -187,6 +191,7 @@ private:
not_null<PeerData*> peer,
Fn<void(Link)> done,
bool revokeLegacyPermanent,
const QString &label = QString(),
TimeId expireDate = 0,
int usageLimit = 0,
bool requestApproval = false);

View File

@ -1180,6 +1180,7 @@ void EditLink(
peer->session().api().inviteLinks().create(
peer,
finish,
result.label,
result.expireDate,
result.usageLimit,
result.requestApproval);
@ -1188,6 +1189,7 @@ void EditLink(
peer,
data.admin,
result.link,
result.label,
result.expireDate,
result.usageLimit,
result.requestApproval,
@ -1202,6 +1204,7 @@ void EditLink(
Ui::EditInviteLinkBox,
Fields{
.link = data.link,
.label = data.label,
.expireDate = data.expireDate,
.usageLimit = data.usageLimit,
.requestApproval = data.requestApproval,

View File

@ -275,6 +275,7 @@ void Row::update(const InviteLinkData &data, TimeId now) {
_progressTillExpire = ComputeProgress(data, now);
_color = ComputeColor(data, _progressTillExpire);
setCustomStatus(ComputeStatus(data, now));
refreshName(st::inviteLinkList.item);
_delegate->rowUpdateRow(this);
}
@ -309,6 +310,9 @@ crl::time Row::updateExpireIn() const {
}
QString Row::generateName() {
if (!_data.label.isEmpty()) {
return _data.label;
}
auto result = _data.link;
return result.replace(
qstr("https://"),

View File

@ -263,13 +263,20 @@ QString ExtractInviteLink(const MTPExportedChatInvite &data) {
});
}
QString ExtractInviteLinkLabel(const MTPExportedChatInvite &data) {
return data.match([&](const MTPDchatInviteExported &data) {
return qs(data.vtitle().value_or_empty());
});
}
QString InternalInviteLinkUrl(const MTPExportedChatInvite &data) {
const auto base64 = ExtractInviteLink(data).toUtf8().toBase64();
return "internal:show_invite_link/?link=" + QString::fromLatin1(base64);
}
QString GenerateInviteLinkText(const MTPExportedChatInvite &data) {
return ExtractInviteLink(data).replace(
const auto label = ExtractInviteLinkLabel(data);
return label.isEmpty() ? ExtractInviteLink(data).replace(
qstr("https://"),
QString()
).replace(
@ -278,7 +285,7 @@ QString GenerateInviteLinkText(const MTPExportedChatInvite &data) {
).replace(
qstr("t.me/joinchat/"),
QString()
);
) : label;
}
QString GenerateInviteLinkLink(const MTPExportedChatInvite &data) {
@ -302,6 +309,11 @@ TextWithEntities GenerateInviteLinkChangeText(
auto result = tr::lng_admin_log_edited_invite_link(tr::now, lt_link, link, Ui::Text::WithEntities);
result.text.append('\n');
const auto label = [](const MTPExportedChatInvite &link) {
return link.match([](const MTPDchatInviteExported &data) {
return qs(data.vtitle().value_or_empty());
});
};
const auto expireDate = [](const MTPExportedChatInvite &link) {
return link.match([](const MTPDchatInviteExported &data) {
return data.vexpire_date().value_or_empty();
@ -327,12 +339,17 @@ TextWithEntities GenerateInviteLinkChangeText(
? QString::number(count)
: tr::lng_group_invite_usage_any(tr::now);
};
const auto wasLabel = label(prevLink);
const auto nowLabel = label(newLink);
const auto wasExpireDate = expireDate(prevLink);
const auto nowExpireDate = expireDate(newLink);
const auto wasUsageLimit = usageLimit(prevLink);
const auto nowUsageLimit = usageLimit(newLink);
const auto wasRequestApproval = requestApproval(prevLink);
const auto nowRequestApproval = requestApproval(newLink);
if (wasLabel != nowLabel) {
result.text.append('\n').append(tr::lng_admin_log_invite_link_label(tr::now, lt_previous, wasLabel, lt_limit, nowLabel));
}
if (wasExpireDate != nowExpireDate) {
result.text.append('\n').append(tr::lng_admin_log_invite_link_expire_date(tr::now, lt_previous, wrapDate(wasExpireDate), lt_limit, wrapDate(nowExpireDate)));
}

View File

@ -24,6 +24,7 @@ namespace {
constexpr auto kMaxLimit = std::numeric_limits<int>::max();
constexpr auto kHour = 3600;
constexpr auto kDay = 86400;
constexpr auto kMaxLabelLength = 32;
[[nodiscard]] QString FormatExpireDate(TimeId date) {
if (date > 0) {
@ -278,6 +279,20 @@ void EditInviteLinkBox(
regenerate();
const auto labelField = container->add(
object_ptr<Ui::InputField>(
container,
st::defaultInputField,
tr::lng_group_invite_label_header(),
data.label),
style::margins(
st::settingsSubsectionTitlePadding.left(),
st::settingsSectionSkip,
st::settingsSubsectionTitlePadding.right(),
st::settingsSectionSkip * 2));
labelField->setMaxLength(kMaxLabelLength);
addDivider(container, tr::lng_group_invite_label_about());
const auto buttonSkip = st::settingsSectionSkip;
const auto requestApproval = container->add(
object_ptr<SettingsButton>(
@ -303,6 +318,7 @@ void EditInviteLinkBox(
? tr::lng_formatting_link_create
: tr::lng_settings_save;
box->addButton(saveLabel(), [=] {
const auto label = labelField->getLastText();
const auto expireDate = (state->expireValue == kMaxLimit)
? 0
: (state->expireValue < 0)
@ -313,6 +329,7 @@ void EditInviteLinkBox(
: state->usageValue;
done(InviteLinkFields{
.link = link,
.label = label,
.expireDate = expireDate,
.usageLimit = usageLimit,
.requestApproval = state->requestApproval.current(),

View File

@ -13,6 +13,7 @@ namespace Ui {
struct InviteLinkFields {
QString link;
QString label;
TimeId expireDate = 0;
int usageLimit = 0;
bool requestApproval = false;