mirror of
https://github.com/kotatogram/kotatogram-desktop
synced 2025-08-31 06:35:14 +00:00
Support topic closing.
This commit is contained in:
@@ -154,6 +154,7 @@ struct TopicUpdate {
|
||||
IconId = (1U << 6),
|
||||
ColorId = (1U << 7),
|
||||
CloudDraft = (1U << 8),
|
||||
Closed = (1U << 9),
|
||||
|
||||
LastUsedBit = (1U << 8),
|
||||
};
|
||||
|
@@ -198,6 +198,14 @@ MsgId ForumTopic::rootId() const {
|
||||
return _rootId;
|
||||
}
|
||||
|
||||
bool ForumTopic::canEdit() const {
|
||||
return (_flags & Flag::My) || channel()->canEditTopics();
|
||||
}
|
||||
|
||||
bool ForumTopic::canToggleClosed() const {
|
||||
return !creating() && canEdit();
|
||||
}
|
||||
|
||||
bool ForumTopic::creating() const {
|
||||
return _forum->creating(_rootId);
|
||||
}
|
||||
@@ -231,13 +239,11 @@ void ForumTopic::applyTopic(const MTPDforumTopic &data) {
|
||||
applyColorId(data.vicon_color().v);
|
||||
|
||||
const auto pinned = _list->pinned();
|
||||
#if 0 // #TODO forum pinned
|
||||
if (data.is_pinned()) {
|
||||
pinned->addPinned(Dialogs::Key(this));
|
||||
} else {
|
||||
pinned->setPinned(Dialogs::Key(this), false);
|
||||
}
|
||||
#endif
|
||||
|
||||
owner().notifySettings().apply(this, data.vnotify_settings());
|
||||
|
||||
@@ -249,19 +255,60 @@ void ForumTopic::applyTopic(const MTPDforumTopic &data) {
|
||||
_rootId,
|
||||
draft->c_draftMessage());
|
||||
}
|
||||
if (data.is_my()) {
|
||||
_flags |= Flag::My;
|
||||
} else {
|
||||
_flags &= ~Flag::My;
|
||||
}
|
||||
setClosed(data.is_closed());
|
||||
|
||||
_replies->setInboxReadTill(
|
||||
data.vread_inbox_max_id().v,
|
||||
data.vunread_count().v);
|
||||
_replies->setOutboxReadTill(data.vread_outbox_max_id().v);
|
||||
applyTopicTopMessage(data.vtop_message().v);
|
||||
#if 0 // #TODO forum unread mark
|
||||
setUnreadMark(data.is_unread_mark());
|
||||
#endif
|
||||
unreadMentions().setCount(data.vunread_mentions_count().v);
|
||||
unreadReactions().setCount(data.vunread_reactions_count().v);
|
||||
}
|
||||
|
||||
bool ForumTopic::closed() const {
|
||||
return _flags & Flag::Closed;
|
||||
}
|
||||
|
||||
void ForumTopic::setClosed(bool closed) {
|
||||
if (this->closed() == closed) {
|
||||
return;
|
||||
} else if (closed) {
|
||||
_flags |= Flag::Closed;
|
||||
} else {
|
||||
_flags &= ~Flag::Closed;
|
||||
}
|
||||
session().changes().topicUpdated(this, UpdateFlag::Closed);
|
||||
}
|
||||
|
||||
void ForumTopic::setClosedAndSave(bool closed) {
|
||||
setClosed(closed);
|
||||
|
||||
const auto api = &session().api();
|
||||
const auto weak = base::make_weak(this);
|
||||
api->request(MTPchannels_EditForumTopic(
|
||||
MTP_flags(MTPchannels_EditForumTopic::Flag::f_closed),
|
||||
channel()->inputChannel,
|
||||
MTP_int(_rootId),
|
||||
MTPstring(), // title
|
||||
MTPlong(), // icon_emoji_id
|
||||
MTP_bool(closed)
|
||||
)).done([=](const MTPUpdates &result) {
|
||||
api->applyUpdates(result);
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
if (error.type() != u"TOPIC_NOT_MODIFIED") {
|
||||
if (const auto topic = weak.get()) {
|
||||
topic->forum()->requestTopic(topic->rootId());
|
||||
}
|
||||
}
|
||||
}).send();
|
||||
}
|
||||
|
||||
void ForumTopic::indexTitleParts() {
|
||||
_titleWords.clear();
|
||||
_titleFirstLetters.clear();
|
||||
|
@@ -61,6 +61,13 @@ public:
|
||||
[[nodiscard]] rpl::producer<> destroyed() const;
|
||||
[[nodiscard]] MsgId rootId() const;
|
||||
|
||||
[[nodiscard]] bool canEdit() const;
|
||||
[[nodiscard]] bool canToggleClosed() const;
|
||||
|
||||
[[nodiscard]] bool closed() const;
|
||||
void setClosed(bool closed);
|
||||
void setClosedAndSave(bool closed);
|
||||
|
||||
[[nodiscard]] bool creating() const;
|
||||
void discard();
|
||||
|
||||
@@ -128,6 +135,13 @@ public:
|
||||
->not_null<HistoryView::SendActionPainter*> override;
|
||||
|
||||
private:
|
||||
enum class Flag : uchar {
|
||||
Closed = (1 << 0),
|
||||
My = (1 << 1),
|
||||
};
|
||||
friend inline constexpr bool is_flag_type(Flag) { return true; }
|
||||
using Flags = base::flags<Flag>;
|
||||
|
||||
void indexTitleParts();
|
||||
void validateDefaultIcon() const;
|
||||
void applyTopicTopMessage(MsgId topMessageId);
|
||||
@@ -158,6 +172,7 @@ private:
|
||||
base::flat_set<QChar> _titleFirstLetters;
|
||||
int _titleVersion = 0;
|
||||
int32 _colorId = 0;
|
||||
Flags _flags;
|
||||
|
||||
std::unique_ptr<Ui::Text::CustomEmoji> _icon;
|
||||
mutable QImage _defaultIcon; // on-demand
|
||||
|
@@ -534,6 +534,15 @@ bool PeerData::canCreateTopics() const {
|
||||
return isForum() && canPinMessages();
|
||||
}
|
||||
|
||||
bool PeerData::canEditTopics() const {
|
||||
if (const auto channel = asChannel()) {
|
||||
return channel->isForum()
|
||||
&& (channel->amCreator()
|
||||
|| (channel->adminRights() & ChatAdminRight::PinMessages));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PeerData::canEditMessagesIndefinitely() const {
|
||||
if (const auto user = asUser()) {
|
||||
return user->isSelf();
|
||||
|
@@ -340,6 +340,7 @@ public:
|
||||
[[nodiscard]] bool canPinMessages() const;
|
||||
[[nodiscard]] bool canEditMessagesIndefinitely() const;
|
||||
[[nodiscard]] bool canCreateTopics() const;
|
||||
[[nodiscard]] bool canEditTopics() const;
|
||||
[[nodiscard]] bool canExportChatHistory() const;
|
||||
|
||||
// Returns true if about text was changed.
|
||||
|
Reference in New Issue
Block a user