mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-14 21:27:07 +02:00
Support group-like channels.
This commit is contained in:
parent
24a7e48b75
commit
9ea495f59d
17 changed files with 152 additions and 46 deletions
|
@ -3584,6 +3584,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
"lng_edit_channel_title" = "Edit channel";
|
||||
"lng_edit_bot_title" = "Edit bot";
|
||||
"lng_edit_sign_messages" = "Sign messages";
|
||||
"lng_edit_sign_messages_about" = "Add names of admins to the messages they post.";
|
||||
"lng_edit_sign_profiles" = "Show authors' profiles";
|
||||
"lng_edit_sign_profiles_about" = "Add names and photos of admins to the messages they post, linking to their profiles.";
|
||||
"lng_edit_group" = "Edit group";
|
||||
"lng_edit_channel_color" = "Change name color";
|
||||
"lng_edit_channel_level_min" = "Level 1+";
|
||||
|
|
|
@ -41,14 +41,14 @@ void InnerFillMessagePostFlags(
|
|||
const SendOptions &options,
|
||||
not_null<PeerData*> peer,
|
||||
MessageFlags &flags) {
|
||||
const auto anonymousPost = peer->amAnonymous();
|
||||
if (ShouldSendSilent(peer, options)) {
|
||||
flags |= MessageFlag::Silent;
|
||||
}
|
||||
if (!anonymousPost || options.sendAs) {
|
||||
if (!peer->amAnonymous()) {
|
||||
flags |= MessageFlag::HasFromId;
|
||||
return;
|
||||
} else if (peer->asMegagroup()) {
|
||||
}
|
||||
const auto channel = peer->asBroadcast();
|
||||
if (!channel) {
|
||||
return;
|
||||
}
|
||||
flags |= MessageFlag::Post;
|
||||
|
@ -57,7 +57,7 @@ void InnerFillMessagePostFlags(
|
|||
return;
|
||||
}
|
||||
flags |= MessageFlag::HasViews;
|
||||
if (peer->asChannel()->addsSignature()) {
|
||||
if (channel->addsSignature()) {
|
||||
flags |= MessageFlag::HasPostAuthor;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3282,9 +3282,9 @@ void ApiWrap::forwardMessages(
|
|||
if (!action.options.scheduled && !action.options.shortcutId) {
|
||||
histories.readInbox(history);
|
||||
}
|
||||
const auto sendAs = action.options.sendAs;
|
||||
const auto anonymousPost = peer->amAnonymous();
|
||||
const auto silentPost = ShouldSendSilent(peer, action.options);
|
||||
const auto sendAs = action.options.sendAs;
|
||||
|
||||
using SendFlag = MTPmessages_ForwardMessages::Flag;
|
||||
auto flags = MessageFlags();
|
||||
|
|
|
@ -1057,19 +1057,50 @@ void Controller::fillSignaturesButton() {
|
|||
return;
|
||||
}
|
||||
|
||||
AddButtonWithText(
|
||||
const auto signs = AddButtonWithText(
|
||||
_controls.buttonsLayout,
|
||||
tr::lng_edit_sign_messages(),
|
||||
rpl::single(QString()),
|
||||
[] {},
|
||||
{ &st::menuIconSigned }
|
||||
)->toggleOn(rpl::single(channel->addsSignature())
|
||||
)->toggledValue(
|
||||
)->toggleOn(rpl::single(channel->addsSignature()));
|
||||
|
||||
const auto profiles = _controls.buttonsLayout->add(
|
||||
object_ptr<Ui::SlideWrap<Ui::SettingsButton>>(
|
||||
_controls.buttonsLayout,
|
||||
EditPeerInfoBox::CreateButton(
|
||||
_controls.buttonsLayout,
|
||||
tr::lng_edit_sign_profiles(),
|
||||
rpl::single(QString()),
|
||||
[] {},
|
||||
st::manageGroupTopButtonWithText,
|
||||
{ &st::menuIconSigned })));
|
||||
profiles->toggleOn(signs->toggledValue());
|
||||
profiles->finishAnimating();
|
||||
|
||||
profiles->entity()->toggleOn(rpl::single(
|
||||
channel->addsSignature() && channel->signatureProfiles()
|
||||
))->toggledValue(
|
||||
) | rpl::start_with_next([=](bool toggled) {
|
||||
_signatureProfilesSavedValue = toggled;
|
||||
}, profiles->entity()->lifetime());
|
||||
|
||||
signs->toggledValue(
|
||||
) | rpl::start_with_next([=](bool toggled) {
|
||||
_signaturesSavedValue = toggled;
|
||||
if (!toggled) {
|
||||
_signatureProfilesSavedValue = false;
|
||||
}
|
||||
}, _controls.buttonsLayout->lifetime());
|
||||
|
||||
_signatureProfilesSavedValue = channel->signatureProfiles();
|
||||
Ui::AddSkip(_controls.buttonsLayout);
|
||||
Ui::AddDividerText(
|
||||
_controls.buttonsLayout,
|
||||
rpl::conditional(
|
||||
signs->toggledValue(),
|
||||
tr::lng_edit_sign_profiles_about(Ui::Text::WithEntities),
|
||||
tr::lng_edit_sign_messages_about(Ui::Text::WithEntities)));
|
||||
Ui::AddSkip(_controls.buttonsLayout);
|
||||
}
|
||||
|
||||
void Controller::fillHistoryVisibilityButton() {
|
||||
|
@ -1227,11 +1258,9 @@ void Controller::fillManageSection() {
|
|||
}
|
||||
if (canEditSignatures) {
|
||||
fillSignaturesButton();
|
||||
}
|
||||
if (canEditPreHistoryHidden
|
||||
} else if (canEditPreHistoryHidden
|
||||
|| canEditForum
|
||||
|| canEditColorIndex
|
||||
|| canEditSignatures
|
||||
//|| canEditInviteLinks
|
||||
|| canViewOrEditLinkedChat
|
||||
|| canEditType) {
|
||||
|
|
|
@ -184,7 +184,11 @@ void ChannelData::setFlags(ChannelDataFlags which) {
|
|||
});
|
||||
}
|
||||
}
|
||||
if (diff & (Flag::Forum | Flag::CallNotEmpty | Flag::SimilarExpanded)) {
|
||||
if (diff & (Flag::Forum
|
||||
| Flag::CallNotEmpty
|
||||
| Flag::SimilarExpanded
|
||||
| Flag::Signatures
|
||||
| Flag::SignatureProfiles)) {
|
||||
if (const auto history = this->owner().historyLoaded(this)) {
|
||||
if (diff & Flag::CallNotEmpty) {
|
||||
history->updateChatListEntry();
|
||||
|
@ -203,6 +207,12 @@ void ChannelData::setFlags(ChannelDataFlags which) {
|
|||
history->owner().requestItemResize(item);
|
||||
}
|
||||
}
|
||||
if (diff & Flag::SignatureProfiles) {
|
||||
history->forceFullResize();
|
||||
}
|
||||
if (diff & (Flag::Signatures | Flag::SignatureProfiles)) {
|
||||
session().changes().peerUpdated(this, UpdateFlag::Rights);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (const auto raw = taken.get()) {
|
||||
|
|
|
@ -1268,9 +1268,12 @@ Data::RestrictionCheckResult PeerData::amRestricted(
|
|||
}
|
||||
|
||||
bool PeerData::amAnonymous() const {
|
||||
return isBroadcast()
|
||||
|| (isChannel()
|
||||
&& (asChannel()->adminRights() & ChatAdminRight::Anonymous));
|
||||
if (const auto channel = asChannel()) {
|
||||
return channel->isBroadcast()
|
||||
? !channel->signatureProfiles()
|
||||
: (channel->adminRights() & ChatAdminRight::Anonymous);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PeerData::canRevokeFullHistory() const {
|
||||
|
|
|
@ -313,19 +313,20 @@ enum class MessageFlag : uint64 {
|
|||
|
||||
// If not set then we need to refresh _displayFrom value.
|
||||
DisplayFromChecked = (1ULL << 40),
|
||||
DisplayFromProfiles = (1ULL << 41),
|
||||
|
||||
ShowSimilarChannels = (1ULL << 41),
|
||||
ShowSimilarChannels = (1ULL << 42),
|
||||
|
||||
Sponsored = (1ULL << 42),
|
||||
Sponsored = (1ULL << 43),
|
||||
|
||||
ReactionsAreTags = (1ULL << 43),
|
||||
ReactionsAreTags = (1ULL << 44),
|
||||
|
||||
ShortcutMessage = (1ULL << 44),
|
||||
ShortcutMessage = (1ULL << 45),
|
||||
|
||||
EffectWatched = (1ULL << 45),
|
||||
EffectWatched = (1ULL << 46),
|
||||
|
||||
SensitiveContent = (1ULL << 46),
|
||||
AllowSensitive = (1ULL << 47),
|
||||
SensitiveContent = (1ULL << 47),
|
||||
AllowSensitive = (1ULL << 48),
|
||||
};
|
||||
inline constexpr bool is_flag_type(MessageFlag) { return true; }
|
||||
using MessageFlags = base::flags<MessageFlag>;
|
||||
|
|
|
@ -730,8 +730,8 @@ bool HistoryInner::canHaveFromUserpics() const {
|
|||
&& !_peer->isRepliesChat()
|
||||
&& !_isChatWide) {
|
||||
return false;
|
||||
} else if (_peer->isChannel() && !_peer->isMegagroup()) {
|
||||
return false;
|
||||
} else if (const auto channel = _peer->asBroadcast()) {
|
||||
return channel->signatureProfiles();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1232,10 +1232,19 @@ PeerData *HistoryItem::computeDisplayFrom() const {
|
|||
}
|
||||
|
||||
PeerData *HistoryItem::displayFrom() const {
|
||||
if (!(_flags & MessageFlag::DisplayFromChecked)) {
|
||||
_flags |= MessageFlag::DisplayFromChecked;
|
||||
_displayFrom = computeDisplayFrom();
|
||||
if (_flags & MessageFlag::DisplayFromChecked) {
|
||||
const auto showing = isPostShowingAuthor();
|
||||
const auto flag = (_flags & MessageFlag::DisplayFromProfiles);
|
||||
if (showing && !flag) {
|
||||
_flags |= MessageFlag::DisplayFromProfiles;
|
||||
} else if (!showing && flag) {
|
||||
_flags &= ~MessageFlag::DisplayFromProfiles;
|
||||
} else {
|
||||
return _displayFrom;
|
||||
}
|
||||
}
|
||||
_flags |= MessageFlag::DisplayFromChecked;
|
||||
_displayFrom = computeDisplayFrom();
|
||||
return _displayFrom;
|
||||
}
|
||||
|
||||
|
@ -2148,7 +2157,7 @@ QString HistoryItem::notificationHeader() const {
|
|||
return QString();
|
||||
} else if (out() && isFromScheduled() && !_history->peer->isSelf()) {
|
||||
return tr::lng_from_you(tr::now);
|
||||
} else if (!_history->peer->isUser() && !isPost()) {
|
||||
} else if (!_history->peer->isUser() && !isPostHidingAuthor()) {
|
||||
return from()->name();
|
||||
}
|
||||
return QString();
|
||||
|
@ -2746,7 +2755,9 @@ bool HistoryItem::inThread(MsgId rootId) const {
|
|||
}
|
||||
|
||||
not_null<PeerData*> HistoryItem::author() const {
|
||||
return (isPost() && !isSponsored()) ? _history->peer : from();
|
||||
return (isPostHidingAuthor() && !isSponsored())
|
||||
? _history->peer
|
||||
: from();
|
||||
}
|
||||
|
||||
TimeId HistoryItem::originalDate() const {
|
||||
|
@ -3092,6 +3103,23 @@ bool HistoryItem::isUploading() const {
|
|||
return _media && _media->uploading();
|
||||
}
|
||||
|
||||
bool HistoryItem::hasRealFromId() const {
|
||||
return !isPost() || (_flags & MessageFlag::HasFromId);
|
||||
}
|
||||
|
||||
bool HistoryItem::isPostHidingAuthor() const {
|
||||
if (!isPost()) {
|
||||
return false;
|
||||
} else if (const auto channel = _history->peer->asBroadcast()) {
|
||||
return !channel->signatureProfiles();
|
||||
}
|
||||
return false; // Should not happen, I guess.
|
||||
}
|
||||
|
||||
bool HistoryItem::isPostShowingAuthor() const {
|
||||
return isPost() && !isPostHidingAuthor();
|
||||
}
|
||||
|
||||
bool HistoryItem::isRegular() const {
|
||||
return isHistoryEntry() && !isLocal();
|
||||
}
|
||||
|
@ -3464,7 +3492,7 @@ ItemPreview HistoryItem::toPreview(ToPreviewOptions options) const {
|
|||
return {};
|
||||
};
|
||||
const auto sender = [&]() -> std::optional<QString> {
|
||||
if (options.hideSender || isPost() || isEmpty()) {
|
||||
if (options.hideSender || isPostHidingAuthor() || isEmpty()) {
|
||||
return {};
|
||||
} else if (!_history->peer->isUser()) {
|
||||
if (const auto from = displayFrom()) {
|
||||
|
|
|
@ -327,6 +327,9 @@ public:
|
|||
[[nodiscard]] bool showSimilarChannels() const {
|
||||
return _flags & MessageFlag::ShowSimilarChannels;
|
||||
}
|
||||
[[nodiscard]] bool hasRealFromId() const;
|
||||
[[nodiscard]] bool isPostHidingAuthor() const;
|
||||
[[nodiscard]] bool isPostShowingAuthor() const;
|
||||
[[nodiscard]] bool isRegular() const;
|
||||
[[nodiscard]] bool isUploading() const;
|
||||
void sendFailed();
|
||||
|
|
|
@ -822,6 +822,14 @@ HistoryWidget::HistoryWidget(
|
|||
updateStickersByEmoji();
|
||||
updateFieldPlaceholder();
|
||||
_preview->checkNow(false);
|
||||
|
||||
const auto was = (_sendAs != nullptr);
|
||||
refreshSendAsToggle();
|
||||
if (was != (_sendAs != nullptr)) {
|
||||
updateControlsVisibility();
|
||||
updateControlsGeometry();
|
||||
orderWidgets();
|
||||
}
|
||||
}
|
||||
if (flags & PeerUpdateFlag::Migration) {
|
||||
handlePeerMigration();
|
||||
|
|
|
@ -23,6 +23,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "core/click_handler_types.h"
|
||||
#include "main/main_session.h"
|
||||
#include "lottie/lottie_icon.h"
|
||||
#include "data/data_channel.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_message_reactions.h"
|
||||
#include "window/window_session_controller.h"
|
||||
|
@ -570,10 +571,14 @@ BottomInfo::Data BottomInfoDataFromMessage(not_null<Message*> message) {
|
|||
if (message->context() == Context::ShortcutMessages) {
|
||||
result.flags |= Flag::Shortcut;
|
||||
}
|
||||
if (const auto msgsigned = item->Get<HistoryMessageSigned>()) {
|
||||
if (!msgsigned->isAnonymousRank) {
|
||||
result.author = msgsigned->author;
|
||||
}
|
||||
if (!item->isPost()
|
||||
|| !item->hasRealFromId()
|
||||
|| !item->history()->peer->asChannel()->signatureProfiles()) {
|
||||
if (const auto msgsigned = item->Get<HistoryMessageSigned>()) {
|
||||
if (!msgsigned->isAnonymousRank) {
|
||||
result.author = msgsigned->author;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (message->displayedEditDate()) {
|
||||
result.flags |= Flag::Edited;
|
||||
|
|
|
@ -1087,7 +1087,7 @@ bool Element::computeIsAttachToPrevious(not_null<Element*> previous) {
|
|||
const auto item = view->data();
|
||||
return !item->isService()
|
||||
&& !item->isEmpty()
|
||||
&& !item->isPost()
|
||||
&& !item->isPostHidingAuthor()
|
||||
&& (!item->history()->peer->isMegagroup()
|
||||
|| !view->hasOutLayout()
|
||||
|| !item->from()->isChannel());
|
||||
|
|
|
@ -408,6 +408,7 @@ Message::Message(
|
|||
Element *replacing)
|
||||
: Element(delegate, data, replacing, Flag(0))
|
||||
, _hideReply(delegate->elementHideReply(this))
|
||||
, _postShowingAuthor(data->isPostShowingAuthor() ? 1 : 0)
|
||||
, _bottomInfo(
|
||||
&data->history()->owner().reactions(),
|
||||
BottomInfoDataFromMessage(this)) {
|
||||
|
@ -2272,10 +2273,11 @@ bool Message::hasFromPhoto() const {
|
|||
case Context::SavedSublist:
|
||||
case Context::ScheduledTopic: {
|
||||
const auto item = data();
|
||||
if (item->isPost()) {
|
||||
if (item->isPostHidingAuthor()) {
|
||||
return false;
|
||||
}
|
||||
if (item->isEmpty()
|
||||
} else if (item->isPost()) {
|
||||
return true;
|
||||
} else if (item->isEmpty()
|
||||
|| (context() == Context::Replies && item->isDiscussionPost())) {
|
||||
return false;
|
||||
} else if (delegate()->elementIsChatWide()) {
|
||||
|
@ -4244,6 +4246,14 @@ int Message::resizeContentGetHeight(int newWidth) {
|
|||
const auto mediaDisplayed = media ? media->isDisplayed() : false;
|
||||
const auto bubble = drawBubble();
|
||||
|
||||
const auto postShowingAuthor = item->isPostShowingAuthor() ? 1 : 0;
|
||||
if (_postShowingAuthor != postShowingAuthor) {
|
||||
_postShowingAuthor = postShowingAuthor;
|
||||
_bottomInfo.update(BottomInfoDataFromMessage(this), newWidth);
|
||||
_fromNameVersion = -1;
|
||||
previousInBlocksChanged();
|
||||
}
|
||||
|
||||
item->resolveDependent();
|
||||
|
||||
// This code duplicates countGeometry() but also resizes media.
|
||||
|
|
|
@ -315,10 +315,11 @@ private:
|
|||
mutable std::unique_ptr<FromNameStatus> _fromNameStatus;
|
||||
Ui::Text::String _rightBadge;
|
||||
mutable int _fromNameVersion = 0;
|
||||
uint32 _bubbleWidthLimit : 29 = 0;
|
||||
uint32 _bubbleWidthLimit : 28 = 0;
|
||||
uint32 _invertMedia : 1 = 0;
|
||||
uint32 _hideReply : 1 = 0;
|
||||
uint32 _rightBadgeHasBoosts : 1 = 0;
|
||||
uint32 _postShowingAuthor : 1 = 0;
|
||||
|
||||
BottomInfo _bottomInfo;
|
||||
|
||||
|
|
|
@ -43,11 +43,16 @@ SendAsPeers::SendAsPeers(not_null<Session*> session)
|
|||
|
||||
bool SendAsPeers::shouldChoose(not_null<PeerData*> peer) {
|
||||
refresh(peer);
|
||||
return Data::CanSendAnything(peer, false) && (list(peer).size() > 1);
|
||||
const auto channel = peer->asBroadcast();
|
||||
return Data::CanSendAnything(peer, false)
|
||||
&& (list(peer).size() > 1)
|
||||
&& (!channel
|
||||
|| channel->addsSignature()
|
||||
|| channel->signatureProfiles());
|
||||
}
|
||||
|
||||
void SendAsPeers::refresh(not_null<PeerData*> peer, bool force) {
|
||||
if (!peer->isMegagroup()) {
|
||||
if (!peer->isChannel()) {
|
||||
return;
|
||||
}
|
||||
const auto now = crl::now();
|
||||
|
@ -117,7 +122,7 @@ not_null<PeerData*> SendAsPeers::ResolveChosen(
|
|||
? i->peer
|
||||
: !list.empty()
|
||||
? list.front().peer
|
||||
: (peer->isMegagroup() && peer->amAnonymous())
|
||||
: peer->amAnonymous()
|
||||
? peer
|
||||
: peer->session().user();
|
||||
}
|
||||
|
|
|
@ -263,9 +263,9 @@ void SetupSendAsButton(
|
|||
|
||||
auto userpic = current->value(
|
||||
) | rpl::filter([=](PeerData *peer) {
|
||||
return peer && peer->isMegagroup();
|
||||
return peer && peer->isChannel();
|
||||
}) | rpl::map([=](not_null<PeerData*> peer) {
|
||||
const auto channel = peer->asMegagroup();
|
||||
const auto channel = peer->asChannel();
|
||||
|
||||
auto updates = rpl::single(
|
||||
rpl::empty
|
||||
|
|
Loading…
Add table
Reference in a new issue