mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-08-31 14:38:15 +00:00
Allow enabling direct messages in channels.
This commit is contained in:
@@ -1168,12 +1168,13 @@ rpl::producer<int> SetupChargeSlider(
|
||||
struct State {
|
||||
rpl::variable<int> stars;
|
||||
};
|
||||
const auto group = !peer->isUser();
|
||||
const auto broadcast = peer->isBroadcast();
|
||||
const auto group = !broadcast && !peer->isUser();
|
||||
const auto state = container->lifetime().make_state<State>();
|
||||
const auto chargeStars = savedValue ? savedValue : kDefaultChargeStars;
|
||||
state->stars = chargeStars;
|
||||
|
||||
Ui::AddSubsectionTitle(container, group
|
||||
Ui::AddSubsectionTitle(container, (group || broadcast)
|
||||
? tr::lng_rights_charge_price()
|
||||
: tr::lng_messages_privacy_price());
|
||||
|
||||
@@ -1225,7 +1226,9 @@ rpl::producer<int> SetupChargeSlider(
|
||||
const auto percent = peer->session().appConfig().paidMessageCommission();
|
||||
Ui::AddDividerText(
|
||||
container,
|
||||
(group
|
||||
(broadcast
|
||||
? tr::lng_manage_monoforum_price_about
|
||||
: group
|
||||
? tr::lng_rights_charge_price_about
|
||||
: tr::lng_messages_privacy_price_about)(
|
||||
lt_percent,
|
||||
@@ -1235,3 +1238,54 @@ rpl::producer<int> SetupChargeSlider(
|
||||
|
||||
return state->stars.value();
|
||||
}
|
||||
|
||||
void EditDirectMessagesPriceBox(
|
||||
not_null<Ui::GenericBox*> box,
|
||||
not_null<ChannelData*> channel,
|
||||
std::optional<int> savedValue,
|
||||
Fn<void(std::optional<int>)> callback) {
|
||||
box->setTitle(tr::lng_manage_monoforum());
|
||||
|
||||
const auto toggle = box->addRow(object_ptr<Ui::SettingsButton>(
|
||||
box,
|
||||
tr::lng_manage_monoforum_allow(),
|
||||
st::settingsButtonNoIcon
|
||||
), {})->toggleOn(rpl::single(savedValue.has_value()));
|
||||
Ui::AddSkip(box->verticalLayout());
|
||||
|
||||
Ui::AddDividerText(
|
||||
box->verticalLayout(),
|
||||
tr::lng_manage_monoforum_about());
|
||||
|
||||
const auto wrap = box->addRow(
|
||||
object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
|
||||
box,
|
||||
object_ptr<Ui::VerticalLayout>(box)),
|
||||
{});
|
||||
wrap->toggle(savedValue.has_value(), anim::type::instant);
|
||||
wrap->toggleOn(toggle->toggledChanges());
|
||||
|
||||
const auto result = box->lifetime().make_state<int>(
|
||||
savedValue.value_or(0));
|
||||
|
||||
const auto inner = wrap->entity();
|
||||
Ui::AddSkip(inner);
|
||||
SetupChargeSlider(
|
||||
inner,
|
||||
channel,
|
||||
savedValue.value_or(0)
|
||||
) | rpl::start_with_next([=](int stars) {
|
||||
*result = stars;
|
||||
}, box->lifetime());
|
||||
|
||||
box->addButton(tr::lng_settings_save(), [=] {
|
||||
const auto weak = Ui::MakeWeak(box);
|
||||
callback(toggle->toggled() ? *result : std::optional<int>());
|
||||
if (const auto strong = weak.data()) {
|
||||
strong->closeBox();
|
||||
}
|
||||
});
|
||||
box->addButton(tr::lng_cancel(), [=] {
|
||||
box->closeBox();
|
||||
});
|
||||
}
|
||||
|
@@ -174,3 +174,9 @@ void EditMessagesPrivacyBox(
|
||||
not_null<Ui::VerticalLayout*> container,
|
||||
not_null<PeerData*> peer,
|
||||
int savedValue);
|
||||
|
||||
void EditDirectMessagesPriceBox(
|
||||
not_null<Ui::GenericBox*> box,
|
||||
not_null<ChannelData*> channel,
|
||||
std::optional<int> savedValue,
|
||||
Fn<void(std::optional<int>)> callback);
|
||||
|
@@ -28,6 +28,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "boxes/peers/replace_boost_box.h"
|
||||
#include "boxes/peers/verify_peers_box.h"
|
||||
#include "boxes/peer_list_controllers.h"
|
||||
#include "boxes/edit_privacy_box.h" // EditDirectMessagesPriceBox
|
||||
#include "boxes/stickers_box.h"
|
||||
#include "boxes/username_box.h"
|
||||
#include "chat_helpers/emoji_suggestions_widget.h"
|
||||
@@ -220,28 +221,41 @@ void SaveSlowmodeSeconds(
|
||||
}
|
||||
|
||||
void SaveStarsPerMessage(
|
||||
std::shared_ptr<Ui::Show> show,
|
||||
not_null<ChannelData*> channel,
|
||||
int starsPerMessage,
|
||||
Fn<void()> done) {
|
||||
Fn<void(bool)> done) {
|
||||
const auto api = &channel->session().api();
|
||||
const auto key = Api::RequestKey("stars_per_message", channel->id);
|
||||
|
||||
const auto broadcast = channel->isBroadcast();
|
||||
|
||||
using Flag = MTPchannels_UpdatePaidMessagesPrice::Flag;
|
||||
const auto broadcastAllowed = broadcast && (starsPerMessage >= 0);
|
||||
const auto requestId = api->request(MTPchannels_UpdatePaidMessagesPrice(
|
||||
MTP_flags(0), // #TODO Support broadcast_messages_allowed flag in UI
|
||||
MTP_flags(broadcastAllowed
|
||||
? Flag::f_broadcast_messages_allowed
|
||||
: Flag(0)),
|
||||
channel->inputChannel,
|
||||
MTP_long(starsPerMessage)
|
||||
)).done([=](const MTPUpdates &result) {
|
||||
api->clearModifyRequest(key);
|
||||
api->applyUpdates(result);
|
||||
channel->setStarsPerMessage(starsPerMessage);
|
||||
done();
|
||||
if (!broadcast) {
|
||||
channel->setStarsPerMessage(starsPerMessage);
|
||||
}
|
||||
done(true);
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
api->clearModifyRequest(key);
|
||||
if (error.type() != u"CHAT_NOT_MODIFIED"_q) {
|
||||
return;
|
||||
show->showToast(error.type());
|
||||
done(false);
|
||||
} else {
|
||||
if (!broadcast) {
|
||||
channel->setStarsPerMessage(starsPerMessage);
|
||||
}
|
||||
done(true);
|
||||
}
|
||||
channel->setStarsPerMessage(starsPerMessage);
|
||||
done();
|
||||
}).send();
|
||||
|
||||
api->registerModifyRequest(key, requestId);
|
||||
@@ -281,6 +295,7 @@ void SaveBoostsUnrestrict(
|
||||
void ShowEditPermissions(
|
||||
not_null<Window::SessionNavigation*> navigation,
|
||||
not_null<PeerData*> peer) {
|
||||
const auto show = navigation->uiShow();
|
||||
auto createBox = [=](not_null<Ui::GenericBox*> box) {
|
||||
const auto saving = box->lifetime().make_state<int>(0);
|
||||
const auto save = [=](
|
||||
@@ -299,7 +314,10 @@ void ShowEditPermissions(
|
||||
channel,
|
||||
result.boostsUnrestrict,
|
||||
close);
|
||||
SaveStarsPerMessage(channel, result.starsPerMessage, close);
|
||||
const auto price = result.starsPerMessage;
|
||||
SaveStarsPerMessage(show, channel, price, [=](bool ok) {
|
||||
close();
|
||||
});
|
||||
}
|
||||
};
|
||||
auto done = [=](EditPeerPermissionsBoxResult result) {
|
||||
@@ -366,6 +384,7 @@ private:
|
||||
std::optional<bool> joinToWrite;
|
||||
std::optional<bool> requestToJoin;
|
||||
std::optional<ChannelData*> discussionLink;
|
||||
std::optional<int> starsPerDirectMessage;
|
||||
};
|
||||
|
||||
[[nodiscard]] object_ptr<Ui::RpWidget> createPhotoAndTitleEdit();
|
||||
@@ -382,8 +401,10 @@ private:
|
||||
void showEditPeerTypeBox(
|
||||
std::optional<rpl::producer<QString>> error = {});
|
||||
void showEditDiscussionLinkBox();
|
||||
void showEditDirectMessagesBox();
|
||||
void fillPrivacyTypeButton();
|
||||
void fillDiscussionLinkButton();
|
||||
void fillDirectMessagesButton();
|
||||
//void fillInviteLinkButton();
|
||||
void fillForumButton();
|
||||
void fillColorIndexButton();
|
||||
@@ -412,6 +433,7 @@ private:
|
||||
[[nodiscard]] bool validateUsernamesOrder(Saving &to) const;
|
||||
[[nodiscard]] bool validateUsername(Saving &to) const;
|
||||
[[nodiscard]] bool validateDiscussionLink(Saving &to) const;
|
||||
[[nodiscard]] bool validateDirectMessagesPrice(Saving &to) const;
|
||||
[[nodiscard]] bool validateTitle(Saving &to) const;
|
||||
[[nodiscard]] bool validateDescription(Saving &to) const;
|
||||
[[nodiscard]] bool validateHistoryVisibility(Saving &to) const;
|
||||
@@ -426,6 +448,7 @@ private:
|
||||
void saveUsernamesOrder();
|
||||
void saveUsername();
|
||||
void saveDiscussionLink();
|
||||
void saveDirectMessagesPrice();
|
||||
void saveTitle();
|
||||
void saveDescription();
|
||||
void saveHistoryVisibility();
|
||||
@@ -454,6 +477,7 @@ private:
|
||||
std::optional<ChannelData*> _discussionLinkSavedValue;
|
||||
ChannelData *_discussionLinkOriginalValue = nullptr;
|
||||
bool _channelHasLocationOriginalValue = false;
|
||||
std::optional<rpl::variable<int>> _starsPerDirectMessageSavedValue;
|
||||
std::optional<HistoryVisibility> _historyVisibilitySavedValue;
|
||||
std::optional<EditPeerTypeData> _typeDataSavedValue;
|
||||
std::optional<bool> _forumSavedValue;
|
||||
@@ -918,6 +942,20 @@ void Controller::showEditDiscussionLinkBox() {
|
||||
}).send();
|
||||
}
|
||||
|
||||
void Controller::showEditDirectMessagesBox() {
|
||||
Expects(_peer->isBroadcast());
|
||||
Expects(_starsPerDirectMessageSavedValue.has_value());
|
||||
|
||||
const auto stars = _starsPerDirectMessageSavedValue->current();
|
||||
_navigation->parentController()->show(Box(
|
||||
EditDirectMessagesPriceBox,
|
||||
_peer->asChannel(),
|
||||
(stars >= 0) ? stars : std::optional<int>(),
|
||||
[=](std::optional<int> value) {
|
||||
*_starsPerDirectMessageSavedValue = value.value_or(-1);
|
||||
}));
|
||||
}
|
||||
|
||||
void Controller::fillPrivacyTypeButton() {
|
||||
Expects(_controls.buttonsLayout != nullptr);
|
||||
|
||||
@@ -983,9 +1021,11 @@ void Controller::fillPrivacyTypeButton() {
|
||||
void Controller::fillDiscussionLinkButton() {
|
||||
Expects(_controls.buttonsLayout != nullptr);
|
||||
|
||||
_discussionLinkSavedValue = _discussionLinkOriginalValue = _peer->isChannel()
|
||||
? _peer->asChannel()->discussionLink()
|
||||
: nullptr;
|
||||
_discussionLinkSavedValue
|
||||
= _discussionLinkOriginalValue
|
||||
= (_peer->isChannel()
|
||||
? _peer->asChannel()->discussionLink()
|
||||
: nullptr);
|
||||
|
||||
const auto isGroup = (_peer->isChat() || _peer->isMegagroup());
|
||||
auto text = !isGroup
|
||||
@@ -1019,6 +1059,33 @@ void Controller::fillDiscussionLinkButton() {
|
||||
{ isGroup ? &st::menuIconChannel : &st::menuIconGroups });
|
||||
_discussionLinkUpdates.fire_copy(*_discussionLinkSavedValue);
|
||||
}
|
||||
|
||||
void Controller::fillDirectMessagesButton() {
|
||||
Expects(_controls.buttonsLayout != nullptr);
|
||||
|
||||
if (!_peer->isBroadcast() || !_peer->asChannel()->canEditInformation()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto monoforumLink = _peer->asChannel()->monoforumLink();
|
||||
_starsPerDirectMessageSavedValue = rpl::variable<int>(
|
||||
monoforumLink ? monoforumLink->starsPerMessage() : -1);
|
||||
|
||||
auto label = _starsPerDirectMessageSavedValue->value(
|
||||
) | rpl::map([](int starsPerMessage) {
|
||||
return (starsPerMessage < 0)
|
||||
? tr::lng_manage_monoforum_off()
|
||||
: !starsPerMessage
|
||||
? tr::lng_manage_monoforum_free()
|
||||
: rpl::single(Lang::FormatCountDecimal(starsPerMessage));
|
||||
}) | rpl::flatten_latest();
|
||||
AddButtonWithText(
|
||||
_controls.buttonsLayout,
|
||||
tr::lng_manage_monoforum(),
|
||||
std::move(label),
|
||||
[=] { showEditDirectMessagesBox(); },
|
||||
{ &st::menuIconChatBubble });
|
||||
}
|
||||
//
|
||||
//void Controller::fillInviteLinkButton() {
|
||||
// Expects(_controls.buttonsLayout != nullptr);
|
||||
@@ -1359,6 +1426,8 @@ void Controller::fillManageSection() {
|
||||
const auto canViewOrEditDiscussionLink = isChannel
|
||||
&& (channel->discussionLink()
|
||||
|| (channel->isBroadcast() && channel->canEditInformation()));
|
||||
const auto canEditDirectMessages = isChannel
|
||||
&& (channel->isBroadcast() && channel->canEditInformation());
|
||||
|
||||
::AddSkip(_controls.buttonsLayout, 0);
|
||||
|
||||
@@ -1370,6 +1439,9 @@ void Controller::fillManageSection() {
|
||||
if (canViewOrEditDiscussionLink) {
|
||||
fillDiscussionLinkButton();
|
||||
}
|
||||
if (canEditDirectMessages) {
|
||||
fillDirectMessagesButton();
|
||||
}
|
||||
if (canEditPreHistoryHidden) {
|
||||
fillHistoryVisibilityButton();
|
||||
}
|
||||
@@ -1973,6 +2045,7 @@ std::optional<Controller::Saving> Controller::validate() const {
|
||||
if (validateUsernamesOrder(result)
|
||||
&& validateUsername(result)
|
||||
&& validateDiscussionLink(result)
|
||||
&& validateDirectMessagesPrice(result)
|
||||
&& validateTitle(result)
|
||||
&& validateDescription(result)
|
||||
&& validateHistoryVisibility(result)
|
||||
@@ -2022,6 +2095,14 @@ bool Controller::validateDiscussionLink(Saving &to) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Controller::validateDirectMessagesPrice(Saving &to) const {
|
||||
if (!_starsPerDirectMessageSavedValue) {
|
||||
return true;
|
||||
}
|
||||
to.starsPerDirectMessage = _starsPerDirectMessageSavedValue->current();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Controller::validateTitle(Saving &to) const {
|
||||
if (!_controls.title) {
|
||||
return true;
|
||||
@@ -2120,6 +2201,7 @@ void Controller::save() {
|
||||
pushSaveStage([=] { saveUsernamesOrder(); });
|
||||
pushSaveStage([=] { saveUsername(); });
|
||||
pushSaveStage([=] { saveDiscussionLink(); });
|
||||
pushSaveStage([=] { saveDirectMessagesPrice(); });
|
||||
pushSaveStage([=] { saveTitle(); });
|
||||
pushSaveStage([=] { saveDescription(); });
|
||||
pushSaveStage([=] { saveHistoryVisibility(); });
|
||||
@@ -2277,6 +2359,30 @@ void Controller::saveDiscussionLink() {
|
||||
}).send();
|
||||
}
|
||||
|
||||
void Controller::saveDirectMessagesPrice() {
|
||||
const auto channel = _peer->asChannel();
|
||||
if (!channel) {
|
||||
return continueSave();
|
||||
}
|
||||
const auto monoforumLink = channel->monoforumLink();
|
||||
const auto current = monoforumLink ? monoforumLink->starsPerMessage() : -1;
|
||||
const auto desired = _savingData.starsPerDirectMessage
|
||||
? *_savingData.starsPerDirectMessage
|
||||
: current;
|
||||
if (desired == current) {
|
||||
return continueSave();
|
||||
}
|
||||
const auto show = _navigation->uiShow();
|
||||
const auto done = [=](bool ok) {
|
||||
if (ok) {
|
||||
continueSave();
|
||||
} else {
|
||||
cancelSave();
|
||||
}
|
||||
};
|
||||
SaveStarsPerMessage(show, channel, desired, crl::guard(this, done));
|
||||
}
|
||||
|
||||
void Controller::saveTitle() {
|
||||
if (!_savingData.title || *_savingData.title == _peer->name()) {
|
||||
return continueSave();
|
||||
|
@@ -907,6 +907,7 @@ void PinsLimitBox(
|
||||
limits.dialogsPinnedPremium(),
|
||||
PinsCount(session->data().chatsList()));
|
||||
}
|
||||
|
||||
void SublistsPinsLimitBox(
|
||||
not_null<Ui::GenericBox*> box,
|
||||
not_null<Main::Session*> session) {
|
||||
|
Reference in New Issue
Block a user