mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-02-20 23:27:23 +00:00
Allow unlinking the discussion group.
This commit is contained in:
parent
f0eba3e283
commit
b9d89cb4a0
@ -847,7 +847,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_manage_discussion_group" = "Discussion";
|
||||
"lng_manage_discussion_group_add" = "Add a group";
|
||||
"lng_manage_linked_channel" = "Linked channel";
|
||||
"lng_manage_linked_channel_set" = "Set";
|
||||
"lng_manage_linked_channel_restore" = "Restore linked channel";
|
||||
"lng_manage_discussion_group_about" = "Select a group chat for discussion that will be displayed in your channel.";
|
||||
"lng_manage_discussion_group_about_chosen" = "A link to {group} is shown to all subscribers in the bottom panel.";
|
||||
"lng_manage_discussion_group_create" = "Create a new group";
|
||||
|
@ -11,8 +11,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "data/data_channel.h"
|
||||
#include "ui/widgets/labels.h"
|
||||
#include "ui/wrap/vertical_layout.h"
|
||||
#include "info/profile/info_profile_button.h"
|
||||
#include "info/profile/info_profile_values.h"
|
||||
#include "boxes/peer_list_box.h"
|
||||
#include "styles/style_boxes.h"
|
||||
#include "styles/style_info.h"
|
||||
|
||||
namespace {
|
||||
|
||||
@ -23,6 +26,145 @@ TextWithEntities BoldText(const QString &text) {
|
||||
return result;
|
||||
}
|
||||
|
||||
class ListController
|
||||
: public PeerListController
|
||||
, public PeerListContentDelegate {
|
||||
public:
|
||||
ListController(Fn<void(not_null<ChannelData*>)> callback)
|
||||
: _callback(std::move(callback)) {
|
||||
}
|
||||
void prepare() override {
|
||||
}
|
||||
void rowClicked(not_null<PeerListRow*> row) override {
|
||||
const auto onstack = _callback;
|
||||
onstack(row->peer()->asChannel());
|
||||
}
|
||||
void peerListSetTitle(Fn<QString()> title) override {
|
||||
}
|
||||
void peerListSetAdditionalTitle(Fn<QString()> title) override {
|
||||
}
|
||||
bool peerListIsRowSelected(not_null<PeerData*> peer) override {
|
||||
return false;
|
||||
}
|
||||
int peerListSelectedRowsCount() override {
|
||||
return 0;
|
||||
}
|
||||
auto peerListCollectSelectedRows()
|
||||
-> std::vector<not_null<PeerData*>> override {
|
||||
return {};
|
||||
}
|
||||
void peerListScrollToTop() override {
|
||||
}
|
||||
void peerListAddSelectedRowInBunch(
|
||||
not_null<PeerData*> peer) override {
|
||||
}
|
||||
void peerListFinishSelectedRowsBunch() override {
|
||||
}
|
||||
void peerListSetDescription(
|
||||
object_ptr<Ui::FlatLabel> description) override {
|
||||
}
|
||||
|
||||
private:
|
||||
Fn<void(not_null<ChannelData*>)> _callback;
|
||||
|
||||
};
|
||||
|
||||
object_ptr<Ui::RpWidget> SetupList(
|
||||
not_null<QWidget*> parent,
|
||||
not_null<ChannelData*> channel,
|
||||
ChannelData *chat,
|
||||
const std::vector<not_null<ChannelData*>> &chats,
|
||||
Fn<void(ChannelData*)> callback) {
|
||||
const auto already = (chat != nullptr);
|
||||
const auto selected = [=](not_null<ChannelData*> chat) {
|
||||
if (already) {
|
||||
Ui::showPeerHistory(chat, ShowAtUnreadMsgId);
|
||||
} else {
|
||||
callback(chat);
|
||||
}
|
||||
};
|
||||
const auto controller = Ui::CreateChild<ListController>(
|
||||
parent.get(),
|
||||
selected);
|
||||
controller->setDelegate(controller);
|
||||
auto list = object_ptr<PeerListContent>(
|
||||
parent,
|
||||
controller,
|
||||
st::peerListBox);
|
||||
const auto createRow = [](not_null<ChannelData*> chat) {
|
||||
auto result = std::make_unique<PeerListRow>(chat);
|
||||
result->setCustomStatus(chat->isPublic()
|
||||
? ('@' + chat->username)
|
||||
: lang(lng_manage_discussion_group_private));
|
||||
return result;
|
||||
};
|
||||
if (chat) {
|
||||
list->appendRow(createRow(chat));
|
||||
} else {
|
||||
for (const auto chat : chats) {
|
||||
list->appendRow(createRow(chat));
|
||||
}
|
||||
}
|
||||
return std::move(list);
|
||||
}
|
||||
|
||||
object_ptr<Ui::RpWidget> SetupAbout(
|
||||
not_null<QWidget*> parent,
|
||||
not_null<ChannelData*> channel,
|
||||
ChannelData *chat) {
|
||||
auto about = object_ptr<Ui::FlatLabel>(
|
||||
parent,
|
||||
QString(),
|
||||
Ui::FlatLabel::InitType::Simple,
|
||||
st::linkedChatAbout);
|
||||
about->setMarkedText([&]() -> TextWithEntities {
|
||||
if (!channel->isBroadcast()) {
|
||||
return lng_manage_linked_channel_about__generic<
|
||||
TextWithEntities
|
||||
>(lt_channel, BoldText(chat->name));
|
||||
} else if (chat != nullptr) {
|
||||
return lng_manage_discussion_group_about_chosen__generic<
|
||||
TextWithEntities
|
||||
>(lt_group, BoldText(chat->name));
|
||||
} else {
|
||||
return { lang(lng_manage_discussion_group_about) };
|
||||
}
|
||||
}());
|
||||
return std::move(about);
|
||||
}
|
||||
|
||||
object_ptr<Ui::RpWidget> SetupCreateGroup(
|
||||
not_null<QWidget*> parent,
|
||||
not_null<ChannelData*> channel) {
|
||||
auto result = object_ptr<Info::Profile::Button>(
|
||||
parent,
|
||||
Lang::Viewer(
|
||||
lng_manage_discussion_group_create
|
||||
) | Info::Profile::ToUpperValue(),
|
||||
st::infoCreateLinkedChatButton);
|
||||
result->addClickHandler([=] {
|
||||
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
object_ptr<Ui::RpWidget> SetupUnlink(
|
||||
not_null<QWidget*> parent,
|
||||
not_null<ChannelData*> channel,
|
||||
Fn<void(ChannelData*)> callback) {
|
||||
auto result = object_ptr<Info::Profile::Button>(
|
||||
parent,
|
||||
Lang::Viewer(channel->isBroadcast()
|
||||
? lng_manage_discussion_group_unlink
|
||||
: lng_manage_linked_channel_unlink
|
||||
) | Info::Profile::ToUpperValue(),
|
||||
st::infoUnlinkChatButton);
|
||||
result->addClickHandler([=] {
|
||||
callback(nullptr);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
EditLinkedChatBox::EditLinkedChatBox(
|
||||
@ -51,90 +193,15 @@ object_ptr<Ui::RpWidget> EditLinkedChatBox::setupContent(
|
||||
Expects(channel->isBroadcast() || (chat != nullptr));
|
||||
|
||||
auto result = object_ptr<Ui::VerticalLayout>(this);
|
||||
const auto about = result->add(
|
||||
object_ptr<Ui::FlatLabel>(
|
||||
result,
|
||||
QString(),
|
||||
Ui::FlatLabel::InitType::Simple,
|
||||
st::linkedChatAbout),
|
||||
result->add(
|
||||
SetupAbout(result, channel, chat),
|
||||
st::linkedChatAboutPadding);
|
||||
about->setMarkedText([&]() -> TextWithEntities {
|
||||
if (!channel->isBroadcast()) {
|
||||
return lng_manage_linked_channel_about__generic<
|
||||
TextWithEntities
|
||||
>(lt_channel, BoldText(chat->name));
|
||||
} else if (chat != nullptr) {
|
||||
return lng_manage_discussion_group_about_chosen__generic<
|
||||
TextWithEntities
|
||||
>(lt_group, BoldText(chat->name));
|
||||
} else {
|
||||
return { lang(lng_manage_discussion_group_about) };
|
||||
}
|
||||
}());
|
||||
|
||||
class ListController
|
||||
: public PeerListController
|
||||
, public PeerListContentDelegate {
|
||||
public:
|
||||
ListController(Fn<void(not_null<ChannelData*>)> callback)
|
||||
: _callback(std::move(callback)) {
|
||||
}
|
||||
void prepare() override {
|
||||
}
|
||||
void rowClicked(not_null<PeerListRow*> row) override {
|
||||
_callback(row->peer()->asChannel());
|
||||
}
|
||||
void peerListSetTitle(Fn<QString()> title) override {
|
||||
}
|
||||
void peerListSetAdditionalTitle(Fn<QString()> title) override {
|
||||
}
|
||||
bool peerListIsRowSelected(not_null<PeerData*> peer) override {
|
||||
return false;
|
||||
}
|
||||
int peerListSelectedRowsCount() override {
|
||||
return 0;
|
||||
}
|
||||
auto peerListCollectSelectedRows()
|
||||
-> std::vector<not_null<PeerData*>> override {
|
||||
return {};
|
||||
}
|
||||
void peerListScrollToTop() override {
|
||||
}
|
||||
void peerListAddSelectedRowInBunch(
|
||||
not_null<PeerData*> peer) override {
|
||||
}
|
||||
void peerListFinishSelectedRowsBunch() override {
|
||||
}
|
||||
void peerListSetDescription(
|
||||
object_ptr<Ui::FlatLabel> description) override {
|
||||
}
|
||||
|
||||
private:
|
||||
Fn<void(not_null<ChannelData*>)> _callback;
|
||||
|
||||
};
|
||||
const auto controller = Ui::CreateChild<ListController>(this, [=](not_null<ChannelData*> chat) {
|
||||
const auto onstack = callback;
|
||||
onstack(chat);
|
||||
});
|
||||
controller->setDelegate(controller);
|
||||
const auto list = result->add(object_ptr<PeerListContent>(
|
||||
this,
|
||||
controller,
|
||||
st::peerListBox));
|
||||
const auto createRow = [](not_null<ChannelData*> chat) {
|
||||
auto result = std::make_unique<PeerListRow>(chat);
|
||||
result->setCustomStatus(chat->isPublic()
|
||||
? ('@' + chat->username)
|
||||
: lang(lng_manage_discussion_group_private));
|
||||
return result;
|
||||
};
|
||||
if (!chat) {
|
||||
result->add(SetupCreateGroup(result, channel));
|
||||
}
|
||||
result->add(SetupList(result, channel, chat, chats, callback));
|
||||
if (chat) {
|
||||
list->appendRow(createRow(chat));
|
||||
} else {
|
||||
for (const auto chat : chats) {
|
||||
list->appendRow(createRow(chat));
|
||||
}
|
||||
result->add(SetupUnlink(result, channel, callback));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -232,6 +232,7 @@ private:
|
||||
|
||||
std::optional<Privacy> _privacySavedValue;
|
||||
std::optional<ChannelData*> _linkedChatSavedValue;
|
||||
ChannelData *_linkedChatOriginalValue = nullptr;
|
||||
std::optional<HistoryVisibility> _historyVisibilitySavedValue;
|
||||
std::optional<QString> _usernameSavedValue;
|
||||
std::optional<bool> _signaturesSavedValue;
|
||||
@ -522,6 +523,10 @@ void Controller::showEditLinkedChatBox() {
|
||||
return;
|
||||
} else if (_linkedChatsRequestId) {
|
||||
return;
|
||||
} else if (channel->isMegagroup()) {
|
||||
// Restore original linked channel.
|
||||
callback(_linkedChatOriginalValue);
|
||||
return;
|
||||
}
|
||||
_linkedChatsRequestId = _linkedChatsRequester.request(
|
||||
MTPchannels_GetGroupsForDiscussion()
|
||||
@ -579,26 +584,39 @@ void Controller::fillPrivacyTypeButton() {
|
||||
void Controller::fillLinkedChatButton() {
|
||||
Expects(_controls.buttonsLayout != nullptr);
|
||||
|
||||
_linkedChatSavedValue = _peer->isChannel()
|
||||
_linkedChatSavedValue = _linkedChatOriginalValue = _peer->isChannel()
|
||||
? _peer->asChannel()->linkedChat()
|
||||
: nullptr;
|
||||
|
||||
const auto isGroup = (_peer->isChat() || _peer->isMegagroup());
|
||||
auto text = !isGroup
|
||||
? Lang::Viewer(lng_manage_discussion_group)
|
||||
: rpl::combine(
|
||||
Lang::Viewer(lng_manage_linked_channel),
|
||||
Lang::Viewer(lng_manage_linked_channel_restore),
|
||||
_linkedChatUpdates.events()
|
||||
) | rpl::map([=](
|
||||
const QString &edit,
|
||||
const QString &restore,
|
||||
ChannelData *chat) {
|
||||
return chat ? edit : restore;
|
||||
});
|
||||
auto label = isGroup
|
||||
? _linkedChatUpdates.events() | rpl::map([](ChannelData *chat) {
|
||||
return chat ? chat->name : QString();
|
||||
}) : rpl::combine(
|
||||
Lang::Viewer(lng_manage_discussion_group_add),
|
||||
_linkedChatUpdates.events()
|
||||
) | rpl::map([=](const QString &add, ChannelData *chat) {
|
||||
return chat
|
||||
? chat->name
|
||||
: add;
|
||||
});
|
||||
AddButtonWithText(
|
||||
_controls.buttonsLayout,
|
||||
Lang::Viewer(isGroup
|
||||
? lng_manage_linked_channel
|
||||
: lng_manage_discussion_group),
|
||||
_linkedChatUpdates.events(
|
||||
) | rpl::map([=](ChannelData *channel) {
|
||||
return channel
|
||||
? channel->name
|
||||
: isGroup
|
||||
? lang(lng_manage_linked_channel_set)
|
||||
: lang(lng_manage_discussion_group_add);
|
||||
}),
|
||||
std::move(text),
|
||||
std::move(label),
|
||||
[=] { showEditLinkedChatBox(); });
|
||||
|
||||
_linkedChatUpdates.fire_copy(*_linkedChatSavedValue);
|
||||
}
|
||||
|
||||
@ -782,6 +800,7 @@ void Controller::fillManageSection() {
|
||||
if (canEditPreHistoryHidden
|
||||
|| canEditSignatures
|
||||
|| canEditInviteLink
|
||||
|| canEditLinkedChat
|
||||
|| canEditUsername) {
|
||||
AddSkip(
|
||||
_controls.buttonsLayout,
|
||||
@ -1297,7 +1316,7 @@ object_ptr<Info::Profile::Button> EditPeerInfoBox::CreateButton(
|
||||
const style::icon *icon) {
|
||||
auto result = object_ptr<Info::Profile::Button>(
|
||||
parent,
|
||||
std::move(text),
|
||||
rpl::duplicate(text),
|
||||
st.button);
|
||||
const auto button = result.data();
|
||||
button->addClickHandler(callback);
|
||||
@ -1307,9 +1326,26 @@ object_ptr<Info::Profile::Button> EditPeerInfoBox::CreateButton(
|
||||
*icon,
|
||||
st.iconPosition);
|
||||
}
|
||||
|
||||
auto labelText = rpl::combine(
|
||||
std::move(text),
|
||||
std::move(count),
|
||||
button->widthValue()
|
||||
) | rpl::map([&st](const QString &text, const QString &count, int width) {
|
||||
const auto available = width
|
||||
- st.button.padding.left()
|
||||
- (st.button.font->spacew * 2)
|
||||
- st.button.font->width(text)
|
||||
- st.labelPosition.x();
|
||||
const auto required = st.label.style.font->width(count);
|
||||
return (required > available)
|
||||
? st.label.style.font->elided(count, std::max(available, 0))
|
||||
: count;
|
||||
});
|
||||
|
||||
const auto label = Ui::CreateChild<Ui::FlatLabel>(
|
||||
button,
|
||||
std::move(count),
|
||||
std::move(labelText),
|
||||
st.label);
|
||||
label->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||
|
||||
|
@ -435,6 +435,13 @@ infoBlockButton: InfoProfileButton(infoProfileButton) {
|
||||
textFg: attentionButtonFg;
|
||||
textFgOver: attentionButtonFgOver;
|
||||
}
|
||||
infoCreateLinkedChatButton: InfoProfileButton(infoMainButton) {
|
||||
padding: margins(73px, 10px, 8px, 8px);
|
||||
}
|
||||
infoUnlinkChatButton: InfoProfileButton(infoCreateLinkedChatButton) {
|
||||
textFg: attentionButtonFg;
|
||||
textFgOver: attentionButtonFgOver;
|
||||
}
|
||||
infoBlockButtonSkip: 8px;
|
||||
|
||||
infoMembersHeader: 56px;
|
||||
@ -610,7 +617,7 @@ manageGroupTopButtonWithText: InfoProfileCountButton(manageGroupButton) {
|
||||
button: InfoProfileButton(infoProfileButton) {
|
||||
padding: margins(22px, 10px, 24px, 8px);
|
||||
}
|
||||
labelPosition: point(22px, 11px);
|
||||
labelPosition: point(22px, 10px);
|
||||
iconPosition: point(0px, 0px);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user