Add to Group / Channel with suggested rights for bots.

This commit is contained in:
John Preston 2022-03-23 14:15:52 +04:00
parent b62c7c76c8
commit a35888a07b
8 changed files with 141 additions and 22 deletions

View file

@ -914,6 +914,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_profile_block_bot" = "Stop and block bot";
"lng_profile_restart_bot" = "Restart bot";
"lng_profile_invite_to_group" = "Add to Group";
"lng_profile_add_bot_as_admin" = "Add to Group or Channel";
"lng_profile_invite_to_channel" = "Add to Channel";
"lng_profile_invite_to_group_about" = "This bot is able to manage a group.";
"lng_profile_invite_to_channel_about" = "This bot is able to manage a channel.";
"lng_profile_add_bot_as_admin_about" = "This bot is able to manage a group or channel.";
"lng_profile_delete_contact" = "Delete";
"lng_profile_set_group_photo" = "Set Photo";
"lng_profile_add_participant" = "Add Members";
@ -1705,6 +1710,16 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_bot_chats_not_found" = "No chats found";
"lng_bot_sure_share_game" = "Share the game with {user}?";
"lng_bot_sure_share_game_group" = "Share the game with «{group}»?";
"lng_bot_groups_manage" = "Groups I manage";
"lng_bot_channels_manage" = "Channels I manage";
"lng_bot_groups" = "Groups";
"lng_bot_add_title" = "Add Bot";
"lng_bot_add_as_admin" = "Add Bot as Admin";
"lng_bot_add_as_member" = "Add Bot as Member";
"lng_bot_sure_add_title" = "Add bot as admin";
"lng_bot_sure_add_text_group" = "Are you sure you want to add this bot as an admin in the group {group}?";
"lng_bot_sure_add_text_channel" = "Are you sure you want to add this bot as an admin in the channel {group}?";
"lng_bot_sure_add" = "Add as admin";
"lng_typing" = "typing";
"lng_user_typing" = "{user} is typing";

View file

@ -25,6 +25,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "mainwindow.h"
#include "lang/lang_keys.h"
#include "history/history.h"
#include "boxes/peers/edit_participant_box.h"
#include "boxes/peers/edit_participants_box.h"
#include "dialogs/dialogs_main_list.h"
#include "window/window_session_controller.h" // showAddContact()
#include "base/unixtime.h"
@ -580,12 +582,42 @@ void AddBotToGroupBoxController::addBotToGroup(not_null<PeerData*> chat) {
return;
}
}
auto send = crl::guard(this, [bot = _bot, chat] {
AddBotToGroup(bot, chat);
});
auto confirmText = tr::lng_bot_sure_invite(tr::now, lt_group, chat->name);
const auto bot = _bot;
const auto close = [=](auto&&...) {
Ui::hideLayer();
Ui::showPeerHistory(chat, ShowAtUnreadMsgId);
};
const auto saveCallback = SaveAdminCallback(
chat,
bot,
close,
close);
auto box = object_ptr<EditAdminBox>(nullptr);
if (chat->isBroadcast()) {
if (bot->botInfo->channelAdminRights) {
box = Box<EditAdminBox>(
chat,
bot,
ChatAdminRightsInfo(bot->botInfo->channelAdminRights),
QString());
}
} else if (bot->botInfo->groupAdminRights) {
box = Box<EditAdminBox>(
chat,
bot,
ChatAdminRightsInfo(bot->botInfo->groupAdminRights),
QString());
}
if (box) {
box->setSaveCallback(saveCallback);
Ui::show(std::move(box));
return;
}
Ui::show(
Ui::MakeConfirmBox({ confirmText, send }),
Ui::MakeConfirmBox({
tr::lng_bot_sure_invite(tr::now, lt_group, chat->name),
crl::guard(this, [=] { AddBotToGroup(bot, chat); }),
}),
Ui::LayerOption::KeepOther);
}

View file

@ -239,6 +239,25 @@ void ApplyUserUpdate(not_null<UserData*> user, const MTPDuserFull &update) {
user->setCommonChatsCount(update.vcommon_chats_count().v);
user->checkFolder(update.vfolder_id().value_or_empty());
user->setThemeEmoji(qs(update.vtheme_emoticon().value_or_empty()));
if (const auto info = user->botInfo.get()) {
const auto group = update.vbot_group_admin_rights()
? ChatAdminRightsInfo(*update.vbot_group_admin_rights()).flags
: ChatAdminRights();
const auto channel = update.vbot_broadcast_admin_rights()
? ChatAdminRightsInfo(
*update.vbot_broadcast_admin_rights()).flags
: ChatAdminRights();
if (info->groupAdminRights != group
|| info->channelAdminRights != channel) {
info->groupAdminRights = group;
info->channelAdminRights = channel;
user->session().changes().peerUpdated(
user,
Data::PeerUpdate::Flag::Rights);
}
}
user->fullUpdated();
}

View file

@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#pragma once
#include "data/data_peer.h"
#include "data/data_chat_participant_status.h"
#include "dialogs/dialogs_key.h"
struct BotInfo {
@ -21,6 +22,9 @@ struct BotInfo {
QString startToken, startGroupToken, shareGameShortName;
Dialogs::EntryState inlineReturnTo;
ChatAdminRights groupAdminRights;
ChatAdminRights channelAdminRights;
};
enum class UserDataFlag {

View file

@ -47,6 +47,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "main/main_session.h"
#include "core/application.h"
#include "core/click_handler_types.h"
#include "settings/settings_common.h"
#include "apiwrap.h"
#include "api/api_blocked_peers.h"
#include "facades.h"
@ -507,12 +508,26 @@ ActionsFiller::ActionsFiller(
void ActionsFiller::addInviteToGroupAction(
not_null<UserData*> user) {
const auto notEmpty = [](const QString &value) {
return !value.isEmpty();
};
AddActionButton(
_wrap,
tr::lng_profile_invite_to_group(),
CanInviteBotToGroupValue(user),
InviteToChatButton(user) | rpl::filter(notEmpty),
InviteToChatButton(user) | rpl::map(notEmpty),
[=] { AddBotToGroupBoxController::Start(user); },
&st::infoIconRequests);
const auto about = _wrap->add(
object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
_wrap.data(),
object_ptr<Ui::VerticalLayout>(_wrap.data())));
about->toggleOn(InviteToChatAbout(user) | rpl::map(notEmpty));
::Settings::AddSkip(about->entity());
::Settings::AddDividerText(
about->entity(),
InviteToChatAbout(user) | rpl::filter(notEmpty));
::Settings::AddSkip(about->entity());
about->finishAnimating();
}
void ActionsFiller::addShareContactAction(not_null<UserData*> user) {

View file

@ -186,15 +186,45 @@ rpl::producer<bool> IsContactValue(not_null<UserData*> user) {
});
}
rpl::producer<bool> CanInviteBotToGroupValue(not_null<UserData*> user) {
if (!user->isBot() || user->isSupport()) {
return rpl::single(false);
[[nodiscard]] rpl::producer<QString> InviteToChatButton(
not_null<UserData*> user) {
if (!user->isBot() || user->isRepliesChat() || user->isSupport()) {
return rpl::single(QString());
}
using Flag = Data::PeerUpdate::Flag;
return user->session().changes().peerFlagsValue(
user,
UpdateFlag::BotCanBeInvited
Flag::BotCanBeInvited | Flag::Rights
) | rpl::map([=] {
return !user->botInfo->cantJoinGroups;
const auto info = user->botInfo.get();
return info->cantJoinGroups
? (info->channelAdminRights
? tr::lng_profile_invite_to_channel(tr::now)
: QString())
: (info->channelAdminRights
? tr::lng_profile_add_bot_as_admin(tr::now)
: tr::lng_profile_invite_to_group(tr::now));
});
}
[[nodiscard]] rpl::producer<QString> InviteToChatAbout(
not_null<UserData*> user) {
if (!user->isBot() || user->isRepliesChat() || user->isSupport()) {
return rpl::single(QString());
}
using Flag = Data::PeerUpdate::Flag;
return user->session().changes().peerFlagsValue(
user,
Flag::BotCanBeInvited | Flag::Rights
) | rpl::map([=] {
const auto info = user->botInfo.get();
return (info->cantJoinGroups || !info->groupAdminRights)
? (info->channelAdminRights
? tr::lng_profile_invite_to_channel_about(tr::now)
: QString())
: (info->channelAdminRights
? tr::lng_profile_add_bot_as_admin_about(tr::now)
: tr::lng_profile_invite_to_group_about(tr::now));
});
}

View file

@ -57,7 +57,9 @@ rpl::producer<not_null<PeerData*>> MigratedOrMeValue(
[[nodiscard]] rpl::producer<bool> NotificationsEnabledValue(
not_null<PeerData*> peer);
[[nodiscard]] rpl::producer<bool> IsContactValue(not_null<UserData*> user);
[[nodiscard]] rpl::producer<bool> CanInviteBotToGroupValue(
[[nodiscard]] rpl::producer<QString> InviteToChatButton(
not_null<UserData*> user);
[[nodiscard]] rpl::producer<QString> InviteToChatAbout(
not_null<UserData*> user);
[[nodiscard]] rpl::producer<bool> CanShareContactValue(
not_null<UserData*> user);

View file

@ -617,17 +617,19 @@ void Filler::addEditContact() {
void Filler::addBotToGroup() {
const auto user = _peer->asUser();
if (!user
|| !user->isBot()
|| user->isRepliesChat()
|| user->botInfo->cantJoinGroups) {
if (!user) {
return;
}
using AddBotToGroup = AddBotToGroupBoxController;
_addAction(
tr::lng_profile_invite_to_group(tr::now),
[=] { AddBotToGroup::Start(user); },
&st::menuIconInvite);
[[maybe_unused]] const auto lifetime = Info::Profile::InviteToChatButton(
user
) | rpl::take(1) | rpl::start_with_next([=](QString label) {
if (!label.isEmpty()) {
_addAction(
label,
[=] { AddBotToGroupBoxController::Start(user); },
&st::menuIconInvite);
}
});
}
void Filler::addNewMembers() {